首頁 web前端 js教程 jQuery自呼叫匿名函數是如何呼叫的?

jQuery自呼叫匿名函數是如何呼叫的?

Aug 01, 2018 pm 04:04 PM
javascript

這篇文章要跟大家介紹的內容是關於jQuery自呼叫匿名函數是如何呼叫的?有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

開啟jQuery原始碼,首先你會看到這樣的程式碼結構:

(function(window,undefined ){
})();
登入後複製

這是一個自呼叫匿名函數。什麼東東呢?在第一個括號內,建立一個匿名函數;第二個括號,立即執行

為什麼要創建這樣一個「自呼叫匿名函數」呢?
透過定義一個匿名函數,創建了一個「私有」的命名空間,該命名空間的變數和方法,不會破壞全域的命名空間。這點非常有用也是一個JS框架必須支援的功能,jQuery被應用在成千上萬的JavaScript程式中,必須確保jQuery創建的變數不能和導入他的程式所使用的變數發生衝突。
接下來看看在自呼叫匿名函數中都實作了什麼功能,依照程式碼順序排列:

(function( window, undefined ) {
// 构造jQuery对象
var jQuery = function( selector, context ) {
    return new jQuery.fn.init( selector, context, rootjQuery );
}
// 工具函数 Utilities
// 异步队列 Deferred
// 浏览器测试 Support
// 数据缓存 Data
// 队列 queue
// 属性操作 Attribute
// 事件处理 Event
// 选择器 Sizzle
// DOM遍历
// DOM操作
// CSS操作
// 异步请求 Ajax
// 动画 FX
// 坐标和大小
window.jQuery = window.$ = jQuery;
})(window);
登入後複製

匿名函數從語法上叫函數直接量,JavaScript語法需要包圍匿名函數的括號,事實上自呼叫匿名函數有兩種寫法:

(function() {
console.info( this );
console.info( arguments );
}( window ) );
登入後複製
(function() {
console.info( this );
console.info( arguments );
})( window );
登入後複製

為什麼要傳入window呢?

透過傳入window變量,使得window由全域變數變成局部變量,當在jQuery程式碼區塊中存取window時,就不需要將作用域鏈回退到頂層作用域,這樣可以更快的存取window;這還不是關鍵所在,更重要的是,將window作為參數傳入,可以在壓縮程式碼時進行最佳化,看看jquery-1.6.1.min.js: (function(a,b){} )(window); // window 被優化為a  
透過以上的介紹,我們大概了解透過()可以使得一個函數表達式立即執行。

匿名函數作為一個“容器”,“容器”內部可以存取外部的變量,而外部環境不能存取“容器”內部的變量,
所以( function(){…} )()內部定義的變數不會和外部的變數發生衝突,俗稱「匿名包裹器」或「命名空間」。

(function () {
// ... 所有的变量和function都在这里声明,并且作用域也只能在这个匿名闭包里
// ...但是这里的代码依然可以访问外部全局的对象
}());
登入後複製

同下面
(function () {/ 內部程式碼/})();

通俗的講,()就是用來求值的,因此這個()任何時候都不能為空,因為它是要計算的。函數解析它只會解析到 {}為止,不會解析到 ()的。

   把表達式放在()中會回傳表達式的值;
   把函數放在()中會回傳函數本身;(function(){}());
   如果()緊接在函數後面,就是表示在呼叫函數,也就是對函數求值:(function(){})();

(function() {
//自执行函数中的内部变量,外部是无法访问的
var name = 'kevin';
})( window );
登入後複製

name  //undefined,無法取得name的值

程式碼在運作過程中,會優先解析【巳宣告的函數】;

          而函數表達式是當執行到它時,才會解析;
          匿名函數是不會單獨寫的,因此它的執行是需要其它函數的調用,通常看到的匿名函數,都是當作參數被傳遞的。而立即執行函數它本身就是個匿名函數,
          js程式執行的順序:
           //巳宣告的函數function test(){}
 //函數表達式var test = function(){}
           //立即執行函數 (function(){})();

立即執行函數配合閉包,在模組化中的應用,其中要明白幾個點:

1、要在函數體後面加括號就能立即調用,則這個函數必須是函數表達式,不能是函數聲明;

2、立即執行函數可以當作是私有作用域,作用域內部可以存取外部的變量,而外部環境是不能存取作用域內部的變數的,因此,立即執行函數是一個封閉的作用域,不會和外部作用域起衝突。
  JQuery使用的就是這種方法,將JQuery程式碼包裹在( function (window,undefined){…jquery程式碼…} (window)中,在全域作用域中呼叫JQuery程式碼時,可以達到保護JQuery內部變數的作用。
3、Module模式,是自執行函數的高階模式,可以非常方便的在各個匿名閉包中以全域物件呼叫閉包函數。                

Module 模式為:

  a.創建一個立即調用的匿名函數表達式
  b.return一個變量,其中這個變量裡包含你要暴露的東西
  c.返回的這個變量將賦值給window

(function () {
var i = 0;
return {
    get: function () {
        return i;
    },
    set: function (val) {
        i = val;
    },
    increment: function () {
        return ++i;
    }
};
} (window));
登入後複製
    // window作为一个带有多个属性的全局对象,上面的代码对于属性的体现其实是方法,它可以这样调用:
    window.get(); // 0
    window.set(3);
    window.increment(); // 4
    window.increment(); // 5

    window.i; // undefined 因为i不是返回对象的属性
    i; // 引用错误: i 没有定义(因为i只存在于闭包)
登入後複製

/

上面就是關於自呼叫匿名函數的解析,那麼這樣的函數它是怎麼被呼叫的呢?*//
以下是關於全域變數的調用,也就是匿名閉包函數的呼叫##*/再次搬離Module模式

Module 模式,也就是匿名閉包的建立與呼叫:

   a.创建一个立即调用的匿名函数表达式
   b.return一个变量,其中这个变量里包含你要暴露的东西
      c.返回的这个变量将赋值给window
登入後複製

window(或者是任意一个全局对象)作为一个带有多个属性的全局对象,也可以把window当成一个参数,以对象的方式,在其它函数中实现调用。用下面的例子说明:

(function ($, YAHOO) {
// 这里,我们的代码就可以使用全局的jQuery对象了,YAHOO也是一样
$.aa = function(){
    //code
}
} (jQuery, YAHOO));
//调用 jQuery.aa();
登入後複製

下面是一个标准的Module模式,通过匿名函数的返回值来返回这个全局变量:

var blogModule = (function () {
var my = {}, privateName = "博客园";

function privateAddTopic(data) {
    // 这里是内部处理代码
}

my.Name = privateName;
my.AddTopic = function (data) {
    privateAddTopic(data);
};

return my;
} ());
//调用 blogModule.my();
登入後複製

在一些大型项目里,将一个功能分离成多个文件是非常重要的,因为可以多人合作易于开发。再回头看看上面的全局参数导入例子,我们能否把blogModule自身传进去呢?答案是肯定的,我们先将blogModule传进去,添加一个函数属性,然后再返回就达到了我们所说的目的:

var blogModule = (function (my) {
my.AddPhoto = function () {
    //添加内部代码  
};
return my;
} (blogModule || {}));
登入後複製


(function (my){
my.AddPhoto = function () {
    //添加内部代码  
};
return my;
})(blogModule || {}));
//调用 blogModule.AddPhoto();
登入後複製

那么,多个自执行函数间是怎么调用的呢?

(function(owner) {
//第一个匿名闭包
owner.debug = true;
//Ajax相关参数配置
owner.ajax = {
    timeout: 10000,
    type: 'post',
    dataType: 'json',
};
})(window.C = {}));
登入後複製

如果第二个函数想调用 全局变量为C中的 对象呢?要怎么写?

(function($, owner) {
//这里调用上面全局变量为C 中的对象呢
if(!C.debug) return false;
var url = 'aaa.html';
mui.ajax({
    url: url,
    dataType: C.ajax.dataType,
    type: C.ajax.type,
});
})(mui, window.app = {});
登入後複製

再举个例子,同样的,不同自执行闭包函数间的调用方法:

(function($, owner) {
//获取语言闭包
owner.getLanguage = function() {
    var language = localStorage.getItem(C.state.field.language);
    if(typeof language == "undefined" || language === null || language == '') {
        var currentLang = navigator.language;
        if(!currentLang)
            currentLang = navigator.browserLanguage;
        language = currentLang.toLowerCase();
        language = language.replace(/-/g, '_');

        if(language != 'en_us' && language != 'zh_cn')
            language = 'en_us';

        localStorage.setItem(C.state.field.language, language);
    }

    //在上面的解析中有说过,Module模式,return 一个变量,这个变量就是要爆露的东西。通过这个函数的全局变量,这个  language  可以在任何地方调用   
    //return一个变量,其中这个变量里包含你要暴露的东西 
    //全局调用  storage.language                                  
    return language;
};
})(mui, window.storage = {}));
登入後複製
(function($, owner) {
owner.language = {};
owner.preload = function(settings){
    var defaults = {
        name: 'i18n',
        language: '',
        path: '/',
        cache: true,
        encoding: 'UTF-8',
        autoReplace: true,
        success: null,
        error: null,
    };
    
    settings = $.extend(defaults, settings);
    if(settings.language === null || settings.language == '') {
        //全局调用  storage.language                                                                            
        settings.language = storage.getLanguage();
    }
}   
})(mui, window.i18n = {});
登入後複製

所以 匿名闭包的调用规则是这样的,立即执行(最后一个括号) (window),如果把window作为一个参数进行传递,那么就把它以对象的方式,在其它函数中实现全局调用。

相关推荐:

js实现模态窗口增加与删除案例分享(纯代码)

js对象类型怎么判断?详解js里的基本类型转换

以上是jQuery自呼叫匿名函數是如何呼叫的?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles