最近讀到了一篇介紹js中this的四種使用場景的文章,感受總結的很好,因此我認真讀了讀,而且動手實踐了其中的demo,與你們共享。原文連接:
https://github.com/alsotang/n...
遇到this,一直要記得這句:函數執行時,this老是指向調用該函數的對象(即:判斷this所在的函數屬於誰)。node
一、函數有所屬對象,則指向所屬對象git
var myObject={ value:100 }; myObject.getValue=function(){ console.log(this.value); console.log(this); return this.value; } console.log(myObject.getValue());
這裏的getValue屬於對象myObject,因此this就指向myObject,執行結果以下:
es6
二、函數沒有所屬對象時,就指向全局對象(window或global)github
var myObject={ value:100 }; myObject.getValue=function(){ var foo=function(){ console.log(this.value); console.log(this); } foo(); return this.value; } console.log(myObject.getValue());
在這裏,foo屬於全局對象,因此foo函數打印的this.value爲undefined。
app
寫到這裏,我又想起setTimeout和setInterval方法也是屬於全局對象的,因此在這兩個函數體內this是指向全局的,因此也是這種狀況,以下:less
var myObject={ value:100 }; myObject.getValue=function(){ setTimeout(function(){ console.log(this.value); console.log(this); },0); return this.value; } console.log(myObject.getValue());
執行結果以下:
函數
因此,若是要獲得想要的結果,就要這樣寫了吧:this
myObject.getValue=function(){ let self=this;//用一個self保存當前的實例對象,即myObject setTimeout(function(){ console.log(self.value); console.log(self); },0); return this.value; } console.log(myObject.getValue());
結果以下:
spa
這又讓我想起來了es6中箭頭函數的妙用了(這個this綁定的是定義時所在的做用域,而不是運行時所在的做用域;箭頭函數其實沒有本身的this,因此箭頭函數內部的this就是外部的this)(可詳看es6教程:http://es6.ruanyifeng.com/#do...箭頭函數),以下:code
var myObject={ value:100 }; myObject.getValue=function(){ // let self=this;//由於用了箭頭函數,因此這句不須要了 setTimeout(()=>{ console.log(this.value); console.log(this); },0); return this.value; } console.log(myObject.getValue());
執行結果同上:
三、使用構造器new一個對象時,this就指向新對象:
var oneObject=function(){ this.value=100; }; var myObj=new oneObject(); console.log(myObj.value);
這裏的this就指向了new出來的新對象myObj,執行結果以下:
四、apply,call,bind改變了this的指向
var myObject={ value:100 } var foo=function(){ console.log(this); console.log(this.value); console.log("..............."); } foo(); foo.apply(myObject); foo.call(myObject); var newFoo=foo.bind(myObject); newFoo();
foo原本指向全局對象window,可是call,apply和bind將this綁定到了myObject上,因此,foo裏面的this就指向了myObject。執行代碼以下: