首頁 >web前端 >js教程 >Javascript物件中關於setTimeout和setInterval的this介紹_javascript技巧

Javascript物件中關於setTimeout和setInterval的this介紹_javascript技巧

WBOY
WBOY原創
2016-05-16 17:51:451049瀏覽

在Javascript裡,setTimeout和setInterval接收第一個參數是一個字串或一個函數,當在一個物件裡面用setTimeout延時呼叫該物件的方法時

複製程式碼 程式碼如下:

function obj() {
this.fn = function() {
alert("ok");
console.log(this);
setTimeout(this.fn, 1000);//直接使用this引用當前物件
}
}
var o = new obj();
o.fn();

然後我們發現上面的程式碼不是想要的結果,原因是setTimeout裡面的this是指向window,所以要呼叫的函數變成window.fn 為undefined ,於是悲劇了。所以問題的關鍵在於得到目前物件的引用,於是有以下三種方法
複製程式碼 程式碼如下:

// 方法一:

function obj() {
this.fn = function() {
alert("ok");
console.log(this(this );
setTimeout(this.fn.bind(this), 1000);//透過Function.prototype.bind 綁定目前物件
}
}
var o = new obj();
o.fn();

這樣可以得到正確的結果,可惜Function.prototype.bind方法是ES5新增的標準,測試了IE系列發現IE6-8都不支持,只有IE9 可以使用。要相容就得簡單的模擬下bind,看下面的程式碼
複製程式碼 程式碼如下:

// 方法二:
function obj() {
this.fn = function() {
alert("ok");
setTimeout((function(a,b){
return function(){
b.call(a);
}
})(this,this.fn), 1000);//類比Function.prototype.bind
}
}
var o = new obj();
o.fn();

先透過一個自執行匿名函數傳當前物件和物件方法進去,也就是裡面的參數a和b,再回傳一個閉包,透過call方法讓this指向正確。以下是比較簡潔的方法
複製程式碼 程式碼如下:

// 方法三:三:三
function obj() {
this.fn = function() {
var that = this;//儲存目前物件this
alert("ok");
setTimeout(function() {
that.fn();
}, 1000);//經由閉包得到目前作用域,好訪問保存好的物件that
}
}
var o = new obj();
o.fn();

上面第三個方法的兩個關鍵點是保存當前對象this為別名that 和通過閉包得到當前作用域,以存取保存好的物件that;當物件方法裡面多層巢狀函數或setTimeout,setInterval等方法遺失this(也就是this不指向目前物件而是window),所以在this指向正確的作用域儲存var that = this就變得很實用了
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn