javascript
JavaScript中七种函数调用方式及对应 this 的含义
http://blog.sina.com.cn/s/blog_621f1e120100rj21.html
?
?
this 在 JavaScript 開(kāi)發(fā)中占有相當(dāng)重要的地位,不過(guò)很多人對(duì)this這個(gè)東西都感覺(jué)到琢磨不透。要真正理解JavaScript的函數(shù)機(jī)制,就非常有必要搞清楚this到底是怎么回事。
函數(shù)調(diào)用方式不同,this 含義也跟著不同。JavaScript語(yǔ)言中有七種調(diào)用函數(shù)方式:
?
第一種:調(diào)用方法
var obj = {
????method: function() { alert(this === obj); }
}
obj.method();
上面這行obj.method()顯然method是作為方法被調(diào)用,這種情況下,函數(shù)體中的this綁定的就是method的宿主對(duì)象,也就是obj。
從這種調(diào)用方式我們得出第一定律:
第一定律:以方法方式調(diào)用函數(shù),this則綁定宿主對(duì)象。
第二種:調(diào)用全局函數(shù)
var method = function(){alert(this === window);}
method();
上面這個(gè)函數(shù)是個(gè)全局函數(shù)。我們知道,全局變量或函數(shù)都相當(dāng)于window對(duì)象的屬性。也就是說(shuō),上面這句實(shí)際上等同于下面這句:
window.method = function(){alert(this === window);}
window.method();
既然這樣,那么這里 this 綁定到 window 對(duì)象就顯而易見(jiàn),很容易理解了。相當(dāng)于方法調(diào)用模式的一個(gè)特例,并不違背第一定律。
第三種:全局函數(shù)內(nèi)調(diào)用內(nèi)部函數(shù)
var m_ext = function() {
????alert(this === window);
????var m_inner = function() {
????????alert(this === window);
????}
????m_inner();
}
m_ext();
執(zhí)行上面這段代碼,你會(huì)驚訝的發(fā)現(xiàn),兩個(gè)布爾表達(dá)式的值都是真。也就是說(shuō)子函數(shù)孫函數(shù),只要是以函數(shù)的方式調(diào)用,this 就鐵了心綁定 window 對(duì)象了。從這種調(diào)用方式我們得出第二定律:
第二定律:不論子函數(shù)孫函數(shù),只要是以函數(shù)的方式調(diào)用,this 就鐵了心綁定 window 對(duì)象。
第四種:方法內(nèi)調(diào)用內(nèi)部函數(shù)
var obj = {};
obj.method = function() {
????alert(this === obj);
????var m_inner = function() {
????????alert(this === window);
????}
????m_inner();
}
obj.method();
執(zhí)行上面這段代碼,第一個(gè)this綁定到obj你不奇怪,第二個(gè)this綁定到window其實(shí)也不奇怪。它仍然遵守第二定律,也就是不論子函數(shù)孫函數(shù),只要是以函數(shù)的方式調(diào)用,this 就鐵了心綁定 window 對(duì)象。
第五種:作為構(gòu)造函數(shù)調(diào)用
function Person(name, age){
????this.name = name;
????this.age = age;
}
var john = new Person('John', 38);
alert(JSON.stringify(john));
你會(huì)說(shuō),哇,這很眼熟。生成某個(gè)類的新對(duì)象啊。Javascript就是這么另類,函數(shù)確實(shí)可以這么調(diào)。
這次彈出的是這樣一個(gè)字符串:{"name":"John","age":38}。哇,這次我明明沒(méi)在函數(shù)定義里寫(xiě)return 語(yǔ)句,它卻主動(dòng)返回了一個(gè)對(duì)象給我。沒(méi)錯(cuò),即便你在函數(shù)定義里return某個(gè)東西,它也不會(huì)理你。(注意:如果你return一個(gè)function就會(huì)有驚喜,不信你試試看)。從這種調(diào)用方式我們得出第三定律:
第三定律:如果在一個(gè)函數(shù)本身沒(méi)有返回值,在其前面加上?new?調(diào)用,就會(huì)創(chuàng)建一個(gè)連接到該函數(shù) prototype 屬性的新對(duì)象,再把?this?綁定到該對(duì)象,然后執(zhí)行該函數(shù),最后返回該對(duì)象。如果該函數(shù)有返回值,且返回值為字符串/數(shù)字/布爾值等簡(jiǎn)單對(duì)象的話,該返回值會(huì)被丟棄。但如果該函數(shù)的返回值為對(duì)象,函數(shù)或者數(shù)組等復(fù)雜對(duì)象的話,該函數(shù)則會(huì)返回該返回值,拋棄this綁定的對(duì)象。據(jù)我測(cè)試,如果返回值是一個(gè)函數(shù)時(shí),該函數(shù)會(huì)返回undefined。我暫時(shí)還不知道為什么會(huì)這樣。
第六種:用函數(shù)對(duì)象的apply方法調(diào)用
var my_concat = function(stra, strb){
????alert(this);
????return stra + '' + strb;
}
var param = ['hello', ' world']
alert(my_concat.apply('bullshit', param));
你一定注意了,在這里 this 綁定的是apply方法的第一個(gè)參數(shù) 'bullshit'。從這里我們得出第四定律:
第四定律:用方法的apply/call方法調(diào)用方法時(shí),this 則被綁定到apply/call方法的第一個(gè)參數(shù)。
想誰(shuí)就是誰(shuí),嗯,吳媽也行。JavaScript的程序員們好幸福哦。
第七種:用函數(shù)對(duì)象的call方法調(diào)用
var my_concat = function(stra, strb){
????alert(this);
????return stra + '' + strb;
}
alert(my_concat.call('bullshit', 'hello',' world'));
對(duì)啦,你或許會(huì)多問(wèn)一句,apply 的第二個(gè)參數(shù)有什么規(guī)定?call方法和apply又有什么不同?嗯 ,真是勤學(xué)好問(wèn),我就再啰嗦一下說(shuō)說(shuō)apply和call:
apply 和 call?的區(qū)別:
apply要求第二個(gè)參數(shù)必須是數(shù)組。否則就會(huì)報(bào)?TypeError: second argument to Function.prototype.apply must be an array.?而call則沒(méi)這么嚴(yán)格啦,第二個(gè)參數(shù)要什么類型?隨意啦,還可以有第三個(gè)第四個(gè)第五個(gè)第六個(gè)....啦。
我想我說(shuō)的夠清楚了。感謝《JavaScript The Good Parts》和《JavaScript Definitive Guide》,要不然我也弄不明白呢!
轉(zhuǎn)載于:https://www.cnblogs.com/tarrying/p/4345493.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的JavaScript中七种函数调用方式及对应 this 的含义的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 转 使用 HttpClient 4 进行
- 下一篇: JavaScript学习笔记(备忘录)