技術(shù)頻道導(dǎo)航
HTML/CSS
.NET技術(shù)
IIS技術(shù)
PHP技術(shù)
Js/JQuery
Photoshop
Fireworks
服務(wù)器技術(shù)
操作系統(tǒng)
網(wǎng)站運(yùn)營(yíng)

贊助商

分類(lèi)目錄

贊助商

最新文章

搜索

詳解(function(){...})()是什么函數(shù),以及它的傳值方法

作者:admin    時(shí)間:2023-4-26 10:25:14    瀏覽:

我今天看到一個(gè)創(chuàng)建String原型對(duì)象的函數(shù),它的結(jié)構(gòu)是(function(){...})()這個(gè)樣子,如下代碼所示:

/* 創(chuàng)建 replaceAll 函數(shù) */
(function(){
    String.prototype.replaceAll  = function(s1,s2){
      return this.replace(new RegExp(s1,"gi"),s2); //g全局 i忽略大小寫(xiě)
    };
})();

因?yàn)橛辛松厦娴暮瘮?shù),我們就可以在程序中使用str.replaceAll()這個(gè)方法了,這里是用它來(lái)實(shí)現(xiàn)字符全替換的功能。

很多人不明白的是,(function(){...})()是個(gè)什么函數(shù)結(jié)構(gòu)?它是怎樣運(yùn)行的?

(function(){...})()是立即執(zhí)行函數(shù)

其實(shí),(function(){...})()是一個(gè)立即執(zhí)行函數(shù),也叫立即調(diào)用IIFE(Immediately Invoked Function Expression)。

立即執(zhí)行函數(shù)還有另一個(gè)寫(xiě)法: (function(){...}()) ,但它與(function(){...})()沒(méi)有任何區(qū)別。

我們都知道傳統(tǒng)的定義函數(shù)是這樣:

function foo(){...} //這是定義,只是讓解釋器知道其存在,不會(huì)運(yùn)行

foo(); //這是語(yǔ)句,解釋器遇到語(yǔ)句會(huì)運(yùn)行它

為什么要IIFE呢? 1:傳統(tǒng)的方法啰嗦。 2:傳統(tǒng)的方法污染全局命名空間。

那么我們這么寫(xiě) function foo(){...}(); 行么?不行,為啥,因?yàn)?code>function foo(){...}這部分只是聲明,對(duì)解釋器來(lái)說(shuō),像是你寫(xiě)了串字符串“function foo(){...}”,它需要的是解析函數(shù),可以用比如eval()來(lái)執(zhí)行它才可以。所以把()直接放聲明后邊是不行的,錯(cuò)誤語(yǔ)法!

然而,我們距離成功相當(dāng)接近,只需要把函數(shù)聲明變成函數(shù)表達(dá)式就可以了。方法非常多,最常見(jiàn)的方法是用一對(duì)()包裹起來(lái):(function foo(){...})();

這就等價(jià)于

var foo= function(){...};
foo();

當(dāng)然,還有很多別的方法可以把聲明變成表達(dá)式:

!function foo(){...}(); 
+function foo(){...}(); 
void function() {...}();

(function(){...})()是如何傳值的?

需要全局對(duì)象的時(shí)候,可以這么傳, 舉例:

void function(global){
  console.log("a's value is: "+global.aa);  //可以獲取全局對(duì)象中aa的值
}(this)

或者

var aa=10;
(function(a){
  console.log("hello world"+a);
})(aa);

JavaScript立即調(diào)用函數(shù)詳解

立即調(diào)用的函數(shù)表達(dá)式(IIFE)是一種在創(chuàng)建函數(shù)后立即執(zhí)行函數(shù)的方法。

IIFE非常有用,因?yàn)樗鼈儾粫?huì)污染全局對(duì)象,而且它們是隔離變量聲明的簡(jiǎn)單方法。

這是定義 IIFE 的語(yǔ)法:

(function() {
  /* */
})()

IIFE 也可以用箭頭函數(shù)定義:

(() => {
  /* */
})()

我們基本上在括號(hào)內(nèi)定義了一個(gè)函數(shù),然后我們追加()以執(zhí)行該函數(shù):(/* function */)()

那些環(huán)繞的括號(hào)實(shí)際上是使我們的函數(shù)在內(nèi)部被視為表達(dá)式的原因。否則,函數(shù)聲明將無(wú)效,因?yàn)槲覀儧](méi)有指定任何名稱(chēng):

 

函數(shù)聲明需要一個(gè)名字,而函數(shù)表達(dá)式則不需要。

你也可以將調(diào)用括號(hào)放在表達(dá)式括號(hào)內(nèi),沒(méi)有區(qū)別,只是樣式偏好: 

(function() {
  /* */
}())

(() => {
  /* */
}())

使用一元運(yùn)算符的替代語(yǔ)法

你可以使用一些更奇怪的語(yǔ)法來(lái)創(chuàng)建 IIFE,但它在現(xiàn)實(shí)世界中很少使用,并且它依賴(lài)于使用任何一元運(yùn)算符,(不適用于箭頭功能):

-(function() {
  /* */
})()

+(function() {
    /* */
  })()

~(function() {
  /* */
})()

!(function() {
  /* */
})()

命名IIFE

IIFE 也可以命名為常規(guī)函數(shù)(不是箭頭函數(shù))。這不會(huì)改變函數(shù)不會(huì)“泄漏”到全局范圍的事實(shí),并且在執(zhí)行后不能再次調(diào)用它:

(function doSomething() {
  /* */
})()

以分號(hào)開(kāi)頭的 IIFE

你可能會(huì)看到這個(gè):

;(function() {
  /* */
})()

這可以防止盲目連接兩個(gè) JavaScript 文件時(shí)出現(xiàn)問(wèn)題。由于 JavaScript 不需要分號(hào),你可能會(huì)在文件的最后一行連接一些語(yǔ)句,從而導(dǎo)致語(yǔ)法錯(cuò)誤。

總結(jié)

本文詳細(xì)介紹了(function(){...})()結(jié)構(gòu)函數(shù),它是一個(gè)立即執(zhí)行函數(shù)的寫(xiě)法,同時(shí)也介紹了它是如何傳值的,以及介紹了一些需要注意的問(wèn)題。通過(guò)本文,相信你對(duì)立即執(zhí)行函數(shù)有了一個(gè)比較充分的了解。

相關(guān)文章
    x
    • 站長(zhǎng)推薦
    /* 左側(cè)顯示文章內(nèi)容目錄 */