Function類型

函數(shù)實際上是對象绩郎。
函數(shù)名是指向函數(shù)的指針。
使用不帶圓括號的函數(shù)名是訪問函數(shù)指針翁逞,而非調(diào)用函數(shù)肋杖。

函數(shù)定義

函數(shù)聲明語法

function sum1(num1,num2){
    return num1+num2;
}

函數(shù)表達式

var sum = function(num1,num2){
    return num1+num2;
};

使用Function構(gòu)造函數(shù)

var sum = new Function("num1","num2","return num1+num2");
//不推薦上面的寫法,原因:這種語法會導致解析兩次代碼(第一次是解析常規(guī)ECMAScript代碼挖函,
//第二次是解析傳入構(gòu)造函數(shù)中的字符串)状植,從而影響性能。

沒有重載

因為ECMAScript函數(shù)不介意傳遞進來多少參數(shù),也不在乎傳進來參數(shù)是什么數(shù)據(jù)類型津畸。也就是說振定,即使定義的函數(shù)只接收兩個參數(shù),在調(diào)用這個函數(shù)時也未必一定要傳遞兩個參數(shù)肉拓》园福可以傳遞一個、三個甚至不傳參數(shù)帝簇。
因為ECMAScript中的參數(shù)在內(nèi)部時用一個數(shù)組來表示。在函數(shù)體內(nèi)可以通過arguments對象來訪問這個參數(shù)數(shù)組靠益,從而獲取傳遞給函數(shù)的每一個參數(shù)丧肴。

function doAdd(){
    if(arguments.length == 1){
        alert(arguments[0]+10);
    }else if(arguments.length == 2){
        alert(arguments[0]+arguments[1]);
    }
}

因此,只能通過檢查傳入函數(shù)中參數(shù)的類型和數(shù)量并作出不同的反應來模仿方法的重載胧后。

函數(shù)聲明與函數(shù)表達式

解析器在向執(zhí)行環(huán)境中加在數(shù)據(jù)時芋浮,對函數(shù)聲明和函數(shù)表達式并非一視同仁。

解析器會率先讀取函數(shù)聲明壳快,并使其在執(zhí)行任何代碼之前可用(可以訪問)纸巷。
而函數(shù)表達式,則必須等到解析器執(zhí)行到它所在的代碼行眶痰,才會真正被解釋執(zhí)行瘤旨。

alert(sum(10,10));
function sum(num1,num2){
    return num1+num2;
}

以上代碼可以正常運行。因為在代碼開始執(zhí)行之前竖伯,解析器已經(jīng)通過一個名為函數(shù)聲明提升(function declaration hoisting)的過程存哲,讀取并將函數(shù)聲明添加到執(zhí)行環(huán)境中。對代碼求值時七婴,JavaScript引擎在第一遍會聲明函數(shù)并將它們放到源代碼樹的頂部祟偷。

因此,即使聲明函數(shù)的代碼在調(diào)用它的代碼后面打厘,JavaScript引擎也能把函數(shù)聲明提升到頂部修肠。
若把函數(shù)聲明改為等價的函數(shù)表達式,就會在執(zhí)行期間導致錯誤户盯。

alert(sum(10,10));
var sum = function(num1,num2){
    return num1+num2;
}

以上代碼會在運行期間產(chǎn)生錯誤嵌施,因為在執(zhí)行到函數(shù)所在的語句之前,變量sum中不會保存有對函數(shù)的引用莽鸭;而且艰管,由于第一行代碼就會導致“unexpected identifier”(意外標識符)錯誤,實際上也不會執(zhí)行到下一行蒋川。

作為值的函數(shù)

因為ECMAScript中的函數(shù)名本身就是變量牲芋,所以函數(shù)也可以作為值來使用。

1、可以像傳遞參數(shù)一樣把一個函數(shù)傳遞給另一個函數(shù)
2缸浦、可以將一個函數(shù)作為另一個函數(shù)的結(jié)果返回夕冲。

function callSomeFunction(someFunction,someArgument){
    return someFunction(someArgument);
}

例如:

function add10(num){
    return num+10;
}

var result1 = callSomeFunction(add10,10);
alert(result1); //20

function getGreeting(name){
    return "Hello,"+name;
}

var result2 = callSomeFunction(getGreeting,"Wonder");
alert(result2); //"Hello,Wonder"

函數(shù)內(nèi)部屬性

函數(shù)內(nèi)部有兩個特殊的對象:arguments和this。

1裂逐、arguments

用途:保存函數(shù)參數(shù)歹鱼。
此對象有一個屬性叫callee,是一個指針卜高,指向擁有這個arguments對象的函數(shù)弥姻。
例如:

function factorial(num){
    if(num<=1){
        return 1;
    }else{
        return num*factorial(num-1);
    }
}
//上面的代碼在函數(shù)有名字并且名字之后也不會改變的情況下,這樣定義是沒有問題掺涛。
//但是這個函數(shù)的執(zhí)行與函數(shù)名緊緊綁在了一起庭敦,為了消除這種緊密耦合的現(xiàn)象,可以像下面這樣使用arguments.callee薪缆。
function factorial(num){
    if(num<=1){
        return 1;
    }else{
        return num*argument.callee(num-1);
    }
}
//重寫后的factorial()函數(shù)的函數(shù)體內(nèi)秧廉,沒有再引用函數(shù)名factorial。
//這樣不管引用函數(shù)時使用的是什么名字拣帽,都可以保證正常完成遞歸調(diào)用疼电。例如:
var trueFactorial = factorial;
factorial = function(){
    return 0;
};
alert(trueFactorial(5));  //120
alert(factorial(5));      //0

2、this

this引用的是函數(shù)執(zhí)行的環(huán)境對象减拭。

windows.color="red";
var o = {color:"blue"};

function sayColor(){
    alert(this.color);
}
sayColor(); //"red"

o.sayColor = sayColor;
o.sayColor(); //"Blue"

ECMAScript 5規(guī)劃了另一個函數(shù)對象屬性:caller蔽豺。這個屬性中保存著調(diào)用當前函數(shù)的函數(shù)的引用。如果在全局作用域中調(diào)用當前函數(shù)拧粪,它的值為null茫虽。

function outer(){
    inner();
}
function inner(){
    alert(inner.caller);
}
outer();

以上代碼會導致警告框中顯示outer()函數(shù)的源代碼。outer()調(diào)用了inner()既们,所以inner.caller指向outer()濒析。為了實現(xiàn)更松散的耦合,也可以通過arguments.callee.caller來訪問相同的信息啥纸。

function outer(){
    inner();
}
function inner(){
    alert(arguments.callee.caller);
}
outer();

若函數(shù)在嚴格模式下運行時,訪問arguments.callee會導致錯誤斯棒。ECMAScript 5還定義了arguments.caller屬性盾致,但是在嚴格模式下訪問它也會導致錯誤,而非嚴格模式下這個屬性適中是undefined荣暮。
定義arguments.callee屬性是為了分清arguments.caller和函數(shù)的caller屬性庭惜。
嚴格模式還有一個限制:不能為函數(shù)的caller屬性賦值,否則會導致錯誤穗酥。

函數(shù)屬性和方法

length屬性:表示函數(shù)希望接受的命名參數(shù)的個數(shù)护赊。

function sayName(name){
    alert(name);
}
function sum(num1,num2){
    return num1+num2;
}
function sayHi(){
    alert("hi");
}
alert(sayName.length);  //1
alert(sum.length);      //2
alert(sayHi.length);    //0

prototype屬性:保存所有實例方法的真正所在惠遏。即諸如toString()和valueOf()等方法都保存在prototype名下,通過各自對象的實例訪問骏啰。

每個函數(shù)都包含兩個非繼承而來的方法:apply()和call()

用途:在特定的作用域中調(diào)用函數(shù)节吮,實際上等于設置函數(shù)體內(nèi)this對象的值。

apply()方法

param:
param1——在其中運行函數(shù)的作用域
param2——參數(shù)數(shù)組(可以是Array實例判耕,也可以是arguments對象透绩。)

function sum(num1,num2){
    return num1+num2;
}
function callSum1(num1,num2){
    return sum.apply(this,arguments);
}
function callSum1(num1,num2){
    return sum.apply(this,[num1,num2];
}
callSum1(10,10); //20
callSum2(10,10); //20

call()方法

param:
param1——在其中運行函數(shù)的作用域
param2——其余參數(shù)都直接傳遞給函數(shù)。即在使用call()方法時壁熄,傳遞給函數(shù)的參數(shù)必須逐個列舉出來帚豪。

function sum(num1,num2){
    return num1+num2;
}
function callSum(num1,num2){
    return sum.call(this,num1,num2);
}
callSum(10,10); //20

實際上,apply()和call()真正強大的地方是能擴充函數(shù)賴以運行的作用域草丧。

windows.color = "red";
var o = {color:"blue"};
function sayColor(){
    alert(this.color);
}
sayColor(); //red

sayColor.call(this);   //red
sayColor.call(window); //red
sayColor.call(o);      //blue

ECMAScript 5還定義了一個方法:bind()狸臣。這個方法會創(chuàng)建一個函數(shù)的實例,其this值會被綁定到傳給bind()函數(shù)的值方仿。

windows.color = "red";
var o = {color:"blue"};
function sayColor(){
    alert(this.color);
}
var objectSayColor = sayColor.bind(o);
objectSayColor(); //blue
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市统翩,隨后出現(xiàn)的幾起案子仙蚜,更是在濱河造成了極大的恐慌,老刑警劉巖厂汗,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件委粉,死亡現(xiàn)場離奇詭異,居然都是意外死亡娶桦,警方通過查閱死者的電腦和手機贾节,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衷畦,“玉大人栗涂,你說我怎么就攤上這事∑碚” “怎么了斤程?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長菩混。 經(jīng)常有香客問我忿墅,道長,這世上最難降的妖魔是什么沮峡? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任疚脐,我火速辦了婚禮,結(jié)果婚禮上邢疙,老公的妹妹穿的比我還像新娘棍弄。我一直安慰自己望薄,他們只是感情好,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布照卦。 她就那樣靜靜地躺著式矫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪役耕。 梳的紋絲不亂的頭發(fā)上采转,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機與錄音瞬痘,去河邊找鬼故慈。 笑死,一個胖子當著我的面吹牛框全,可吹牛的內(nèi)容都是我干的察绷。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼津辩,長吁一口氣:“原來是場噩夢啊……” “哼拆撼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起喘沿,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤闸度,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蚜印,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體莺禁,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年窄赋,在試婚紗的時候發(fā)現(xiàn)自己被綠了哟冬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡忆绰,死狀恐怖浩峡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情错敢,我是刑警寧澤红符,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站伐债,受9級特大地震影響预侯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜峰锁,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一萎馅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧虹蒋,春花似錦糜芳、人聲如沸飒货。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽塘辅。三九已至,卻和暖如春皆撩,著一層夾襖步出監(jiān)牢的瞬間扣墩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工扛吞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留呻惕,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓滥比,卻偏偏與公主長得像亚脆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子盲泛,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,237評論 0 4
  • 原文:http://dmitrysoshnikov.com/ecmascript/javascript-the-c...
    jaysoul閱讀 478評論 0 0
  • 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的 JavaScript 類型 使用基本類型和基本包裝類型 引用類型的...
    悶油瓶小張閱讀 683評論 0 0
  • 作者:Dmitry A. Soshnikov編譯地址:http://dmitrysoshnikov.com/ecm...
    IT程序獅閱讀 3,342評論 2 12
  • 大家好,我是牛犢網(wǎng)&陌籌君的創(chuàng)始合伙人張巖玛迄。一個90后創(chuàng)業(yè)者由境。今天介紹下我的工作經(jīng)歷和體會棚亩,希望能夠給剛踏入職場或...
    16b53de01cf1閱讀 1,197評論 0 1