JavaScript是一種解釋型語言,函數聲明會在JavaScript代碼加載后、執行前被解釋,而函數表達式只有在執行到這一行代碼時才會被解釋。
在JS中有兩種定義函數的方式,
1是:var aaa=function(){...}
2是:function aaa(){...}
var 方式定義的函數,不能先調用函數,后聲明,只能先聲明函數,然后調用。
function方式定義函數可以先調用,后聲明。
var func=function 和 function func()在意義上沒有任何不同,但其解釋優先級不同: 后者會先於同一語句級的其他語句。
即: { var k = xx(); function xx(){return 5;} } 不會出錯, 而 { var k = xx(); var xx = function(){return 5;} } 則會出錯。
我們來看一下:
var p=function(){}();
這段代碼是什么意思。
看了下面這幾個例子后,大家就會一目了然了。
var p = function(){return 'abc';}(); alert(p);//abc alert(typeof p); //string
var p = function(){return 111;}(); alert(p);//111 alert(typeof p); //number
現在明白了吧,其實就是定義了一個變量,這個變量是后面函數的返回值。
用Javascript 兩大特點,也是JS引擎的實現必然導致的:
1) 返回值。在JS引擎中,所有的語法,操作都有返回值,而且通常返回值是它本身或undefined。通常我們可以用"()"操作符,來獲取當前句子的返回值(部分操作符不能用,如var)。例如:a=3;其實這行的返回值就是3,所以在a=b=3時,JS引擎就可以正確的執行下去,首先3賦值給b,然后當前的返回值3再賦值給a(而不是大家所認為的,先將3賦值給b,然后再將b賦值給a)。又例如函數var fun=function(){},當JS引擎執行到這行時,會先執行右邊,返回值是一個函數的字面量,然后將這個函數字面量賦值給fun。
Jquery也是利用了這個特性(函數return this),所以才有鏈式調用。我們看個例子:"fontFamily".replace( /([A-Z])/g, "-$1" ).toLowerCase(),沒錯這里也是利用了返回值,所以這行的結果是:font-family。
2) 閉包。子函數調用父函數的變量(非傳參),就是閉包。在JS中,子函數能訪問父函數的變量,這時被引用的變量不會釋放,而且子函數中能一直持有這個變量的引用。
結合以上兩大特點,可以生成一個力量強大的怪胎:
(function(){})();
不知道專業的名稱,我叫它為:立即執行匿名函數。
首先在第一對括號內,是一個匿名函數,第二個括號會立即調用這個匿名函數的返回值,也就是匿名函數中的內容被立即執行。
這個怪胎的強大在於,它獨立了一個作用域(括號中內容執行完后會被立即回收),內部變量外部無法訪問,而它又能通過this保留字,來訪問外部變量。
舉個例子:
var i=100; (function(){ var j=1; this.plus_ij = function(){ j+=i; alert(j); } })(); plus_ij();
plus_ij();
上面的例子中,立即執行匿名函數,可以訪問到外部變量i,甚至可以var定義一個i(也不會影響外部的i值)。而且內部變量j形成了一個閉包,不會釋放。
(function(){ var a = function(){} function b(){} this.c = function(){ a(); b(); } })(); c();
上面的例子,你會發現,無論哪種定義方式,在立即執行匿名函數外,都無法訪問到a和b函數。也就是a和b函數成了這個立即執行匿名函數的內部函數,外部無法調用,除了通過這個立即執行匿名函數內部定義的外部函數。
轉自:http://www.cnblogs.com/yongtaiyu/articles/3200722.html