除去第三章說的 var 申明一個(gè)變量外凄诞,還可以用
function
申明一個(gè)函數(shù)對(duì)象
function foo(){}
function
圆雁,見名知意就是函數(shù),既然是函數(shù)就可以用來運(yùn)算帆谍。比如最簡(jiǎn)單的加法
function add(a,b){
var result = a+b;
return result ;
}
先說一下函數(shù)的主體結(jié)構(gòu)伪朽。
-
function
申明接下來是一個(gè)函數(shù)對(duì)象 -
add
說明了這個(gè)函數(shù)的名稱,如果不寫就是一個(gè)匿名函數(shù) <anonymous> -
()
代表這個(gè)函數(shù)的參數(shù)部分 -
a汛蝙、b
在參數(shù)部分有兩個(gè)參數(shù)烈涮,分別是a和b,如果沒有參數(shù)就省略4窖剑,但是3還是要保留坚洽。 -
{ }
這里不是對(duì)象{}
,而代表的是函數(shù)的主體內(nèi)容西土。 -
var result = a+b;
實(shí)際分解為:
var result;
result = a+b;
-
return
是這個(gè)函數(shù)結(jié)尾的部分讶舰,返回后面跟隨的執(zhí)行結(jié)果result。假如這個(gè)函數(shù)沒有返回值可以不寫需了。
調(diào)用該add函數(shù)時(shí)跳昼,使用
add(1,2);
就會(huì)得到結(jié)果 3 。
作用域和變量提升
在函數(shù)里面有一個(gè)作用域【scope】[1]的概念,同時(shí)還有一個(gè)var
關(guān)鍵字的變量提升肋乍,變量提升和作用域是息息相關(guān)的鹅颊。
其實(shí)變量提升我已經(jīng)寫下來了,反觀add第六步住拭,就是變量提升分解示意挪略。
變量提升后的完整的第六步:
function add(a,b){
var result;
result = a+b;
return result ;
}
變量提升將變量的申明部分提升到作用域(函數(shù)體)的頂部,也就是執(zhí)行時(shí)函數(shù)體的第一條語句滔岳。
為什么會(huì)有這種操作?這是因?yàn)閖s語言設(shè)計(jì)缺陷挽牢,允許不申明就使用:
s = 1;
直接的賦值谱煤,并沒有用var或者function聲明這個(gè)s。這在別的語言中禽拔,很顯然是不符合先申明再使用的規(guī)范的刘离。并且室叉,沒有申明直接使用的變量他的作用域不是當(dāng)前的函數(shù)體,而是頂級(jí)的宿主對(duì)象[2]硫惕,存在變量的作用域提升茧痕,會(huì)給開發(fā)者造成不必要的問題。所以恼除,為了防止這種現(xiàn)象踪旷,在作用域頂部,引入 'use strict'
嚴(yán)格模式豁辉,嚴(yán)格檢查當(dāng)前作用域未申明的情況令野。
function sub(){
'use strict'
s = 1;
}
在調(diào)用 sub函數(shù)是就會(huì)報(bào)引用錯(cuò)誤 ReferenceError: s is not defined
引申:在函數(shù)式編程中,提出了“函數(shù)是一等公民”的思想徽级,強(qiáng)調(diào)函數(shù)式編程的純凈[3]
不能不說 this
默認(rèn)情況下气破,this指向當(dāng)前函數(shù)的擁有者。
在瀏覽器下:
function owner(){
return this;
}
owner() ;// Window
即使這個(gè)函數(shù)寫在另一個(gè)函數(shù)體內(nèi)
function owner(){
return function(){
return this;
};
}
owner()() ;// Window
重要的 arguments
js的函數(shù)在執(zhí)行時(shí)餐抢,所有的參數(shù)列表都是由arguments這個(gè)內(nèi)置屬性管控的现使,所有的參數(shù)列表都是可以通過arguments來取值。
function argsTest(){
return arguments.length;
}
argsTest(1,2,3) // 3
argsTest(1,2) // 2
argsTest() // 0
這樣做是因?yàn)閖s并不能函數(shù)重載[4]旷痕,同名函數(shù)只能定義一次碳锈,多次定義之后就會(huì)直接覆蓋:
function reloadFn(){}
function reloadFn(name){}
其實(shí)這個(gè)可以看作
var reloadFn;
reloadFn = function(){}
reloadFn = function(name){}
所以只會(huì)保留最后一次定義的值,這樣就不難理解了苦蒿。因此對(duì)于js來說沒有重載的必要殴胧,但是又想實(shí)現(xiàn)重載的功能,所以就有了arguments佩迟。
arguments本身是一個(gè)類似數(shù)組团滥,但是沒有數(shù)組的某些函數(shù)。不過可以通過 Array.prototype.slice.call(arguments) 重新構(gòu)建一個(gè)數(shù)組报强。這樣灸姊,就可以當(dāng)作數(shù)組來