摘要:當(dāng)函數(shù)是聲明語(yǔ)句的一部分是,他就是函數(shù)表達(dá)式。當(dāng)執(zhí)行流到達(dá)函數(shù)表達(dá)式被創(chuàng)建,結(jié)果是,函數(shù)表達(dá)式只有他們被執(zhí)行后才能使用。這樣的函數(shù)叫匿名函數(shù)。總體來(lái)說(shuō),推薦使用函數(shù)聲明,除非有原因需要使用函數(shù)表達(dá)式。
函數(shù)聲明與表達(dá)式
函數(shù)和變量一樣,可以在代碼的任何地方定義。
JavaScript提供一些方式去定義方法:
函數(shù)聲明
函數(shù)表達(dá)式
函數(shù)作為另一個(gè)函數(shù)結(jié)果被調(diào)用
語(yǔ)法基本創(chuàng)建函數(shù)的語(yǔ)法是函數(shù)聲明。語(yǔ)法如下:
function f(arg1, arg2, ...) { ... code ... }
比如:
function sayHi(name) { alert("Hi, "+name) } sayHi("John")
這個(gè)例子聲明一個(gè)只有一個(gè)參數(shù)的函數(shù)sayHi,運(yùn)行sayHi。
返回值用return聲明來(lái)返回值
function sum(a, b) { return a+b } var result = sum(2,5) alert(result)
如果函數(shù)沒(méi)有返回值,結(jié)果被認(rèn)為是一個(gè)特殊值“undefined”。如下例:
function getNothing() { // no return } var result = getNothing() alert(result)
返回空值也是一樣結(jié)果:
function getNothing() { return } alert( getNothing() === undefined ) // true局部變量
函數(shù)內(nèi)可以包含變量,用var來(lái)定義。這種變量叫做局部變量,只能被內(nèi)部函數(shù)訪問(wèn)。
function sum(a, b) { var sum = a + b return sum }
創(chuàng)建一個(gè)函數(shù)min(a,b),接收兩個(gè)數(shù)字,返回一個(gè)較小的值。
min(2, 5) == 2
min(3, -1) == -1
答案
方案一 用if判斷:
function min(a, b) { if (a < b) { return a } else { return b } }
方案二 用三目運(yùn)算符:
function min(a, b) { return a < b ? a : b // 如果是true運(yùn)行a,否則運(yùn)行b }
寫(xiě)一個(gè)函數(shù)pow(x,n)返回x的n次方,或者說(shuō),x被自己乘了n次。
pow(3, 2) = 3*3 = 9
pow(3, 3) = 333 = 27
pow(1, 100) = 11...*1 = 1
function(x,n){ var result for(var i = 0;i函數(shù)聲明 函數(shù)聲明在預(yù)執(zhí)行階段(當(dāng)瀏覽器準(zhǔn)備執(zhí)行代碼)解析。所以函數(shù)聲明在前后都能被調(diào)用到。
function sayHi(name) { alert("Hi, "+name) } sayHi("John")sayHi("John") function sayHi(name) { alert("Hi, "+name) }所以函數(shù)在任何位置都可以聲明
比如,我們可能希望根據(jù)條件聲明不同的函數(shù)
sayHi() if (1) { function sayHi() { alert(1) } } else { function sayHi() { alert(2) } // <-- }嘗試在不同瀏覽器中運(yùn)行這個(gè)例子。火狐會(huì)報(bào)錯(cuò),其他瀏覽器輸出2。
那是因?yàn)槁暶髟趫?zhí)行前被傳遞了。根據(jù)文檔(p.10.5),后同名的函數(shù),后
聲明的會(huì)覆蓋存在的函數(shù)。當(dāng)執(zhí)行時(shí),其他聲明會(huì)被忽略,所以if語(yǔ)句沒(méi)有任何效果。
函數(shù)表達(dá)式
JavaScript中函數(shù)是一等公民,和數(shù)字字符一樣。
在任何你可以寫(xiě)值的地方,你都可以寫(xiě)函數(shù)。函數(shù)表達(dá)式的語(yǔ)法function(arguments) { ... }舉例,你可以寫(xiě)
var f = 5但你也可以賦函數(shù)表達(dá)式
var f = function(name) { alert("Hi, " + name + "!"); }什么時(shí)候函數(shù)是表達(dá)式,什么時(shí)候是聲明呢?
規(guī)則很簡(jiǎn)單。
但javascript解析器在主代碼流中,他會(huì)認(rèn)為這是函數(shù)聲明。
當(dāng)函數(shù)是聲明語(yǔ)句的一部分是,他就是函數(shù)表達(dá)式。當(dāng)執(zhí)行流到達(dá)函數(shù)表達(dá)式被創(chuàng)建,結(jié)果是,函數(shù)表達(dá)式只有他們被執(zhí)行后才能使用。
var sayHi // sayHi() <-- 這里不能執(zhí)行,還沒(méi)有sayHi函數(shù) if (1) { sayHi = function() { alert(1) } } else { sayHi = function() { alert(2) } } sayHi()上述代碼所有瀏覽器執(zhí)行結(jié)果相同。
請(qǐng)用聲明
經(jīng)驗(yàn)不足的開(kāi)發(fā)人員寫(xiě)的代碼中,方法經(jīng)常用表達(dá)式來(lái)聲明:var f = function() { ... }函數(shù)聲明更加可讀簡(jiǎn)潔,還是用函數(shù)聲明吧。
function f() { ... }除此以外,函數(shù)聲明可在定義前調(diào)用。
只有你在執(zhí)意要用函數(shù)表達(dá)式時(shí)采用。如例子中,條件性的函數(shù)定義。函數(shù)是值
javascript中的函數(shù)是一般值,我們可以輸出他。function f() { alert(1) } alert(f)上面這個(gè)輸出函數(shù)的例子。通常用作源代碼。( Usually as the source code.)
Both declarations and expression declare a variable and put the function into it. Only the creation time is different.
聲明和表達(dá)式都可以作為變量的值。只是創(chuàng)建的時(shí)間不同。傳遞函數(shù)
函數(shù)和任何值一樣可以被賦值,做為其他函數(shù)的參數(shù)傳遞等。
如下例,怎么定義函數(shù)沒(méi)有關(guān)系。
function sayHi(name) { alert("Hi, "+name) } var hi = sayHi // 把函數(shù)賦值給變量 hi("dude") // 執(zhí)行函數(shù)函數(shù)通過(guò)引用被賦值。函數(shù)保存在內(nèi)存的某處,sayHi是它的引用(指向)。當(dāng)我把函數(shù)賦值給hi,變量開(kāi)始引用同一個(gè)函數(shù)。
一個(gè)函數(shù)可以接受另一個(gè)函數(shù)做為參數(shù)
function runWithOne(f) { // 運(yùn)行做為參數(shù)1的函數(shù) f(1) } runWithOne( function(a){ alert(a) } )邏輯上說(shuō),函數(shù)是一個(gè)動(dòng)作.那么,傳遞函數(shù)是傳遞一個(gè)動(dòng)作,能夠在程序另一部分來(lái)初始化。這種特性在javascript中被廣泛使用。
在上面的例子中,我們創(chuàng)建一個(gè)沒(méi)有名字的函數(shù),沒(méi)有賦值給任何變量。這樣的函數(shù)叫匿名函數(shù)。
就地執(zhí)行
可以用函數(shù)表達(dá)式創(chuàng)建并立即運(yùn)行函數(shù),像這樣:
(function() { var a, b // 局部變量 // ... // 其他代碼 })()立即執(zhí)行函數(shù)大多被用在我們想做一些圍繞局部變量的事情。我們不想我們的局部變量變成全局,所以包含在函數(shù)里面。
在執(zhí)行后,全局命名空間還是很干凈,很好的實(shí)踐。
那為什么函數(shù)在括號(hào)中?是因?yàn)閖avascript只允許函數(shù)表達(dá)式立即執(zhí)行。
函數(shù)聲明不能被這樣用:
function work() { // ... }() // 語(yǔ)法錯(cuò)誤即使我們?nèi)サ裘Q(chēng),javaScript會(huì)看到關(guān)鍵詞函數(shù),嘗試轉(zhuǎn)換成函數(shù)聲明。
function() { // 錯(cuò)誤,沒(méi)有名稱(chēng)的函數(shù)聲明。 // ... }()那么。唯一的方式是把函數(shù)用括號(hào)包起來(lái)。就會(huì)打斷他被認(rèn)為是聲明的一部分,所以是函數(shù)表達(dá)式。
如果函數(shù)是一個(gè)明顯的表達(dá)式,那就沒(méi)必要包起來(lái),如下:
var result = function(a,b) { return a+b }(2,2) alert(result) // 4在上面的代碼中,函數(shù)被創(chuàng)建且立即調(diào)用。
就像var result = sum(2,2),用sum函數(shù)替換函數(shù)表達(dá)式。下面的代碼執(zhí)行結(jié)果是什么?為什么?
var a = 5 (function() { alert(a) })()答案:
答案是error,嘗試下面代碼:var a = 5 (function() { alert(a) })()在var a = 5后面沒(méi)有分號(hào)。JavaScript把代碼認(rèn)為是:
var a = 5(function() { alert(a) })()那么,他會(huì)嘗試運(yùn)行5做為一個(gè)函數(shù),這就會(huì)造成錯(cuò)誤。能運(yùn)行的代碼如下:
var a = 5; (function() { alert(a) })()這可能JavaScript中是最危險(xiǎn)隱蔽的不寫(xiě)分號(hào)。
還有一種方式直接調(diào)用函數(shù)構(gòu)造器。把參數(shù)列表和函數(shù)作為字符串,用他們創(chuàng)建函數(shù)。var sayHi = new Function("name", " alert("Hi, "+name) "); sayHi("Benedict");這種方式用的很少很少,幾乎不用。
命名函數(shù)表達(dá)式
一個(gè)函數(shù)表達(dá)式可有名字:var f = function sayHi(name) { alert("Hi, "+name) }語(yǔ)法叫命名函數(shù)表達(dá)式(NFE)在任何瀏覽器都可用除了IE9以下。
在那些支持的瀏覽器中,名字只在函數(shù)內(nèi)可見(jiàn)
var f = function sayHi(name) { alert(sayHi) // 輸出函數(shù) } alert(sayHi) // 錯(cuò)誤:為定義的變量"sayHi"在這種情況IE會(huì)創(chuàng)建兩個(gè)函數(shù)對(duì)象:sayHi和f:
var f = function g() { } // IE中是false,其他瀏覽器報(bào)錯(cuò)(g為定義) alert(f=== g)NEFS存在是為了遞歸匿名函數(shù)。
觀察下面代碼片段被包在serTimeout中調(diào)用:setTimeout(function factorial(n) { return n == 1 ? n : n*factorial(n-1) }, 100)代碼的結(jié)果是什么?為什么?
( function g() { return 1 } ) alert(g)答案:
結(jié)果是error:( function g() { return 1 } ) alert(g)解決方案的關(guān)鍵是理解(function ... )是一個(gè)函數(shù)表達(dá)式(參考本章),不是函數(shù)聲明。
那么,我們有一個(gè)有名函數(shù)表達(dá)式。
有名函數(shù)表達(dá)式的名字只在內(nèi)部可見(jiàn)。
除了IE9.0以下,所有瀏覽器都支持NFEs,那么他們會(huì)給出錯(cuò)誤“undefined variable”,因?yàn)間只有在函數(shù)內(nèi)部可見(jiàn)。
ie9.0以下不支持NFE,就會(huì)輸出函數(shù)
函數(shù)命名
函數(shù)是一個(gè)動(dòng)作。所以命名應(yīng)該是動(dòng)詞,像get,read,caculateSum,等等。
短函數(shù)名稱(chēng)的規(guī)則:一個(gè)函數(shù)是臨時(shí)的且只使用在附近的代碼。變量的短命名可用這個(gè)邏輯。
一個(gè)函數(shù)用在代碼任何地方。一方米昂,沒(méi)有忘記他的危險(xiǎn),另一方面,你可以寫(xiě)的更少。
真實(shí)的例子‘$’, ‘$$’, ‘$A’, ‘$F’ 等。
JavaScript庫(kù)中頻繁調(diào)用的函數(shù)用這些短名稱(chēng)。
其他情況,函數(shù)的名字應(yīng)該是一個(gè)動(dòng)詞,或者一個(gè)動(dòng)詞開(kāi)頭的多個(gè)詞疊加。總結(jié)
JavaScript中函數(shù)是普通值。他們可以按需求被賦值,傳遞,調(diào)用。
一個(gè)不返回值的函數(shù)事實(shí)上會(huì)返回一個(gè)特殊值:undefined。
使用動(dòng)詞命名函數(shù)。短命名允許被用在兩種情況:被用在附近代碼塊,或被非常廣泛使用。
總體來(lái)說(shuō),推薦使用函數(shù)聲明,除非有原因需要使用函數(shù)表達(dá)式。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/78813.html
摘要:示例代碼執(zhí)行上下文創(chuàng)建階段在這個(gè)階段上下文對(duì)象會(huì)生成,并創(chuàng)建變量對(duì)象創(chuàng)建作用域鏈確定的指向。全局對(duì)象是作用域鏈的頭,還意味著在頂層代碼中聲明的所有變量都將成為全局對(duì)象的屬性。 變量對(duì)象 這一節(jié)聊一下變量對(duì)象。都是干貨(^▽?zhuān)? 變量對(duì)象是函數(shù)運(yùn)行時(shí)數(shù)據(jù)的集合,存儲(chǔ)了在上下文中定義的變量和函數(shù),不同的函數(shù)的變量對(duì)象稍有不同。 還是從上下文說(shuō)起,javascript 引擎執(zhí)行到函數(shù)的時(shí)候會(huì)...
摘要:是微軟開(kāi)發(fā)的的超集,兼容,可以載入代碼然后運(yùn)行。可處理已有的代碼,并只對(duì)其中的代碼進(jìn)行編譯小編我決定使用白鷺引擎開(kāi)發(fā)游戲,在開(kāi)發(fā)游戲之前學(xué)習(xí)一下,目前它的可視化工具已經(jīng)可以打多端包了是一套完整的游戲開(kāi)發(fā)解決方案。中包含多個(gè)工具以及項(xiàng)目。 TypeScript 是微軟開(kāi)發(fā)的 JavaScript 的超集,TypeScript兼容JavaScript,可以載入JavaScript代碼然后運(yùn)...
摘要:注意申明的權(quán)重函數(shù)的形參申明聲明聲明也就之前提高的變量提升第部分執(zhí)行先執(zhí)行,再執(zhí)行兩個(gè),再執(zhí)行函數(shù)表達(dá)式申明,及執(zhí)行。 一段代碼看出JS的的解析到執(zhí)行的順序規(guī)則 代碼 function bar(a, b) { b = 3; var b; function b(){} console.log(a); // 打印出:10 console.log(b)...
閱讀 2782·2021-10-11 11:08
閱讀 1498·2021-09-30 09:48
閱讀 1059·2021-09-22 15:29
閱讀 1044·2019-08-30 15:54
閱讀 986·2019-08-29 15:19
閱讀 537·2019-08-29 13:12
閱讀 3172·2019-08-26 13:53
閱讀 975·2019-08-26 13:28