关于setTimeout函数中的this指向问题
為什么setTimeout函數的延遲執行函數中this指向window,但是延遲執行函數是箭頭函數this指向obj?
根據下面的兩點原因解釋,foo和foo2中的this都指向obj,但是其中setTimeout,它的第二個this指向應該是window,至于為什么foo2的this也指向obj,原因在于foo2中setTimeout的第一個參數是箭頭函數,箭頭函數沒有自己的this,它的this跟父級的this指向一致,都指向obj。
var obj = {name: 'name',foo: function () {console.log(this); // Object {name: "name"}setTimeout(function () {console.log(this); // Window}, 1000);},foo2: function () {console.log(this); // Object {name: "name"}setTimeout(() => {console.log(this); // Object {name: "name"}}, 2000);} }原因在于:
setTimeout函數掛載在window對象下,《javascript高級程序設計》中寫道:“超時調用的代碼都是在全局作用域中執行的,因此函數中的this在非嚴格模式下指向window對象,在嚴格模式下是undefined。將setTimeout調用環境下的this稱為第一個this,將延遲執行函數中的this稱為第二個this,此時有結論:
1.第一個this的指向是需要根據上下文來確定的,默認為window;2.第二個this的指向是固定的,就是指向window;對于結論1的證明:
1.函數作為方法調用還是構造函數調用,this是不同的
2.在外層添加一層代碼,第二個this可以訪問到window上的value
var value=33; function Foo() {this.value = 42;this.method = function() {// this 指向全局對象alert(this) // 輸出window 第二個thisalert(this.value); // 輸出:33 第二個this};setTimeout(this.method, 500); // 這里的this指向Foo的實例對象 第一個this } new Foo();可以看出method方法中的this指向window,因為可以輸出外層value的值。
那么為什么setTimeout中的this指向的就是Foo的實例對象呢?
在setTimeout中的this是可以根據上下文而改變的。
接下來驗證一下:
Foo()執行的時候,method方法放到外層,此時setTimeout中的this.method中的this指向window,因此可以調用到method方法。method方法中的this仍然指向window,當Foo()執行的時候,對window.value進行了賦值this.value=42,此時輸出42.
結論:
setTimeout中的第一個this的指向是根據上下文來確定的,默認指向window。對于結論2的證明:
1.直接使用
2.在一個對象中調用
var obj = {say:function(){setTimeout('console.log(this)',1);} } obj.say() //Window3.將執行的代碼換成匿名函數
var obj = {say:function(){setTimeout(function(){console.log(this);},1);} } obj.say() //Window4.將執行的代碼換成函數引用
function talk(){console.log(this); } var obj = {say:function(){setTimeout(talk,1);} } obj.say() //Window結論:
setTimeout中的延遲執行函數中的this指向window;總結
以上是生活随笔為你收集整理的关于setTimeout函数中的this指向问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【iOS】Cocoa(iOS,OSX)安
- 下一篇: 实现web前端录屏并下载到本地(利用Re