因為JavaScript 中this 是在運行期進行綁定的,因此JavaScript 中this 關鍵字具備多重含義。
具體在實際應用中,this的指向大致可以分為下面4種。
- 作為對象的方法調用 obj.a()
- 作為普通函數調用 a()
- 構造函數調用 var b = new a();
- function.prototype.call或function.prototype.apply調用
作為對象的方法調用 和 作為普通函數調用
1 window.a = 2; 2 var obj = { 3 a:1, 4 getA:function(){ 5 console.log(this.a); 6 } 7 } 8 obj.getA(); //輸出1,作為對象的方法調用,this指向當前對象 9 var x = obj.getA; 10 x(); //輸出2,作為普通函數調用,this全部指向window對象。
注意,不管x之前是obj.getA,還是其他某個對象的屬性,只要最后是以x(),fun()這種方式調用的,均視為普通函數調用,此時this指向window對象
但是,在ECMAScript5的strict模式下,作為函數調用的 this被規定不會指向全局對象
1 window.a = 2; 2 var obj = { 3 a:1, 4 getA:function(){ 5 "use strict" 6 console.log(this.a); 7 } 8 } 9 var x = obj.getA; 10 x(); //underfined
作為構造函數調用
通常情況下,構造函數里的this指向返回的這個對象,但是如果構造器
顯示地返回了一個
object類型的對象,則this指向這個返回的object對象
1 var Myclass = function(){ 2 this.name = 'beidan'; 3 } 4 var obj = new Myclass(); 5 console.log(obj.name);//beidan 6 7 var Myclass = function(){ 8 this.name = 'beidan'; 9 return{ //顯示的返回一個對象,注意!既要是顯示,即有return,也要是對象{} 10 name:'test' 11 } 12 } 13 var obj = new Myclass(); 14 console.log(obj.name);//test
作為function.prototype.call或function.prototype.apply調用
- 理解call,apply
call,apply都是為了改變函數體內部 this 的指向。例如,fun1.call()或者fun1.apply() 都是為了改變fun1函數內部的this指向。
二者的作用完全一樣,只是接受參數的方式不太一樣。
func1.call(this,
arg1, arg2); //參數列表arg1,arg2
func1.apply(this,
[arg1, arg2]); //參數數組 [arg1,arg2]
第一個參數指定那個了
函數體內this對象的指向,他可以任何一個 JavaScript 對象(JavaScript 中一切皆對象),如果為null,則函數體內的this會指向默認的宿主對象,在瀏覽器中則是window。
第二個參數,call 需要把參數按順序傳遞進去,而 apply 則是把參數放在數組里。
當你的
參數不確定數量時用 apply ,然后把參數 push 進數組傳遞進去。或者也可以通過 arguments來獲取所有的參數。這樣看來,apply的使用率更高。
- call,apply的用途
1.修正this的指向
比如,在實際開發中,會出現以下這種問題
1 document.getElementById('div1').onclick = function(){ 2 console.log(this.id); //div1 3 var func = function(){ 4 console.log(this.id); 5 } 6 func(); //通過普通函數調用,this指向window,輸出undefined 7 }
這時我們可以用call來修正
func 函數內this的指向。
1 document.getElementById('div1').onclick = function(){ 2 console.log(this.id); //div1 3 var func = function(){ 4 console.log(this.id); 5 } 6 func.call(this); //使用call,使func函數內部的this指向當前的函數對象,輸出div1 7 }
2.模擬繼承(借用其他對象的方法)
- 例子一:其他對象(banana)借用apple中的say方法
1 function fruits() {} 2 fruits.prototype = { 3 color: "red", 4 say: function() { 5 console.log("My color is "+ this.color); 6 } 7 } 8 var apple = new fruits; 9 apple.say(); //My color is red
那么,我們可以用apply或者call 借用 fruit里面的say方法
1 banana = { 2 color: "yellow" 3 }; 4 orange = {color:‘orange’}; 5 apple.say.call(banana); //My color is yellow 6 apple.say.apply(orange ); //My color is orange
再看幾個例子鞏固記憶
- 例子二:獲取數組中的最大值和最小值
1 var numbers = [5, 458 , 120 , -215 ]; 2 var maxInNumbers = Math.max.apply(Math, numbers), //458 3 maxNumbers = Math.max.call(Math,5, 458 , 120 , -215, 666); //666
以上就是this在JavaScript中不同情況下的指向。
如果這篇文章對你有幫助,就給我一點贊賞吧~~~