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