js立即執(zhí)行函數(shù)

js中(function(){...})()立即執(zhí)行函數(shù)寫法理解

轉(zhuǎn)自segmentfault chic
https://segmentfault.com/a/1190000003031456

函數(shù)聲明:function fnName(){...} 使用function關(guān)鍵字聲明一個(gè)函數(shù),再指定一個(gè)函數(shù)名,叫函數(shù)聲明

函數(shù)表達(dá)式:var fnName = function(){...} 使用function關(guān)鍵字聲明一個(gè)函數(shù),但未給函數(shù)命名,最后將匿名函數(shù)賦予一個(gè)變量,叫函數(shù)表達(dá)式,這是最常見的函數(shù)表達(dá)式語法形式。

匿名函數(shù):function(){} 使用function關(guān)鍵字聲明一個(gè)函數(shù),但未給函數(shù)命名,所以叫匿名函數(shù),匿名函數(shù)屬于函數(shù)表達(dá)式,匿名函數(shù)有很多作用,賦予一個(gè)變量則創(chuàng)建函數(shù),賦予一個(gè)事件則成為事件處理程序或創(chuàng)建閉包等等

函數(shù)聲明和函數(shù)表達(dá)式不同之處在于:

  1. Javascript引擎在解析javascript代碼時(shí)會‘函數(shù)聲明提升’(Function declaration
    Hoisting)當(dāng)前執(zhí)行環(huán)境(作用域)上的函數(shù)聲明,而函數(shù)表達(dá)式必須等到Javascirtp引擎執(zhí)行到它所在行時(shí),才會從上而下一行一行地解析函數(shù)表達(dá)式。
  2. 函數(shù)表達(dá)式后面可以加括號立即調(diào)用該函數(shù),函數(shù)聲明不可以,只能以fnName()形式調(diào)用 。

以下是兩者差別的兩個(gè)例子:

fnName();
function fnName(){
    ...
}
//正常,因?yàn)椤嵘撕瘮?shù)聲明,函數(shù)調(diào)用可以在函數(shù)聲明之前

fnName()
var fnName = function(){
    ...
}
//報(bào)錯(cuò),變量fnName還未保存對函數(shù)的引用,函數(shù)調(diào)用必須再函數(shù)表達(dá)式之后

var fnName = function(){
    alert('Hello World')
}()
//函數(shù)表達(dá)式后面加括號,當(dāng)javascript引擎解析到此處時(shí)能立即調(diào)用函數(shù)

function fnName(){
    alert('Hello World')
}()
//不會報(bào)錯(cuò),但是javascript引擎只解析函數(shù)聲明,忽略后面的括號,函數(shù)聲明不會被調(diào)用

function(){
    console.log('Hello World')
}
//語法錯(cuò)誤,雖然匿名函數(shù)屬于函數(shù)表達(dá)式,但是未進(jìn)行賦值操作
//所以javascript引擎將開頭的function關(guān)鍵字當(dāng)作函數(shù)聲明,報(bào)錯(cuò):要求需要一個(gè)函數(shù)名

在函數(shù)體后面加括號就能立即調(diào)用,則這個(gè)函數(shù)必須是函數(shù)表達(dá)式,不能是函數(shù)聲明

(function(a){
    console.log(a)
})()
//輸出123,使用()運(yùn)算符

(function(a){
    console.log(a)
}(1234))
//輸出1234,使用()運(yùn)算符

!function(a){
    console.log(a)
}(12345)
//輸出12345,使用!運(yùn)算符

+function(a){
    console.log(a)
}(123456)
//輸出123456,使用+運(yùn)算符

-function(a){
    console.log(a)
}(1234567)
//輸出1234567,使用-運(yùn)算符

var fn = function(a){
    console.log(a)
}(12345678)
//輸出12345678,使用=運(yùn)算符

可以看到輸出結(jié)果,在function前面加!、=、-、甚至是逗號等都可以起到函數(shù)定義后立即執(zhí)行的效果,而()、!、+、-、=等運(yùn)算符,都將函數(shù)聲明轉(zhuǎn)換成函數(shù)表達(dá)式,消除了JavaScript引擎識別函數(shù)表達(dá)式和函數(shù)聲明的歧義,告訴javascr引擎這是一個(gè)函數(shù)表達(dá)式,不是函數(shù)聲明,可以在后面加括號,并立即執(zhí)行函數(shù)代碼。加括號是最安全的做法,因?yàn)?!?、-等運(yùn)算符還會和函數(shù)的返回值進(jìn)行運(yùn)算,有時(shí)造成不必要的麻煩。

JavaScript中沒有私有作用域的概念,如果在多人開發(fā)的項(xiàng)目上,你在全局或局部作用域中聲明了一些變量,可能會被其他人不小心用同名的變量給覆蓋掉,根據(jù)javascript函數(shù)作用域鏈的特性,可以使用這種技術(shù)可以模仿一個(gè)私用作用域,用匿名函數(shù)作為一個(gè)“容器”,“容器”內(nèi)部可以訪問外部的變量,而外部環(huán)境不能訪問“容器”內(nèi)部的變量,所以(function(){...})()內(nèi)部定義的變量不會和外部的變量發(fā)生沖突,俗稱“匿名包裹器”或“命名空間”。jQuery使用的就是這種方法,將jQuery代碼包裹在(function(window,undefined){...})(window)中,在全局作用域中調(diào)用jQuery代碼時(shí),可以達(dá)到保護(hù)jQuery內(nèi)部變量的作用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 【轉(zhuǎn)載】https://my.oschina.net/u/2331760/blog/468672?p=%7B%7B...
    丿inane丶閱讀 252評論 0 0
  • ( function(){…} )()和( function (){…} () )是兩種javascript立即執(zhí)...
    古水木閱讀 282評論 1 1
  • 1.什么是立即執(zhí)行函數(shù)只有表達(dá)式才可以被()符號執(zhí)行。在了解立即執(zhí)行函數(shù)之前先明確一下函數(shù)聲明、函數(shù)表達(dá)式及匿名函...
    WangYatao閱讀 432評論 0 0
  • 引:原文 | 譯文 一種私有變量創(chuàng)建方式,也是閉包的應(yīng)用之一。 但是,很多時(shí)候,我們不需要函數(shù)聲明,不需要后續(xù)的在...
    DHFE閱讀 534評論 0 0
  • 通過立即函數(shù)可以創(chuàng)建一個(gè)獨(dú)立的作用域。這個(gè)作用域中的變量,外面訪問不到。比如你參與了一個(gè)多人協(xié)作一起開發(fā)的項(xiàng)目,你...
    奮斗live閱讀 467評論 0 2

友情鏈接更多精彩內(nèi)容