首頁 >web前端 >前端問答 >javascriptthis是什麼意思

javascriptthis是什麼意思

青灯夜游
青灯夜游原創
2021-10-20 13:55:089953瀏覽

在js中,this的意思是“這個;當前”,是一個指標型變量,它動態指向當前函數的運行環境。在不同的場景中呼叫同一個函數,this的指向也可能會發生變化,但是它永遠指向其所在函數的真實呼叫者;如果沒有呼叫者,就指向全域物件window。

javascriptthis是什麼意思

本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。

JavaScript 函數被呼叫後會在一個特定的運行環境內執行,這個運行環境就是函數的呼叫者,或者說是呼叫函數的物件。如果函數沒有調用者(不是透過物件調用,而是直接調用),那麼運行環境就是全域物件 window。

為了在函數執行過程中能夠引用(存取)運行環境,JavaScript 專門增加了一個 this 關鍵字。 this 是一個指標型變量,它指向目前函數的運行環境。

在不同的場景中呼叫同一個函數,this 的指向也可能會發生變化,但是它永遠指向其所在函數的真實呼叫者(誰呼叫就指向誰);如果沒有呼叫者,this就指向全域物件window。

在《JS this和呼叫物件》一節中我們曾講到 this 指針的初步使用,不了解的讀者請猛擊鏈接學習,本節重點對 this 指針進行深度剖析。

使用this

this 是由JavaScript 引擎在執行函數時自動產生的,存在於函數內的一個動態指針,指涉當前呼叫對象。具體用法如下:

this[.属性]

如果 this 未包含屬性,則傳遞的是目前物件。

this 用法靈活,其包含的值也是變化多端。例如,下面範例使用 call() 方法不斷改變函數內 this 指涉物件。

var x = "window";  //定义全局变量x,初始化字符串为“window”
function a () {  //定义构造函数a
    this.x = "a";  //定义私有属性x,初始化字符a
}
function b () {  //定义构造函数b
    this.x = "b";  //定义私有属性x,初始化为字符b
}
function c () {  //定义普通函数,提示变量x的值
    console.log(x);
}
function f () {  //定义普通函数,提示this包含的x的值
    console.log(this.x);
}
f();  //返回字符串“window”,this指向window对象
f.call(window);  //返回字符串“window”,指向window对象
f.call(new a());  //返回字符a,this指向函数a的实例
f.call(new b());  //返回字符b,this指向函数b的实例
f.call(c);  //返回undefined,this指向函数c对象

以下簡單總結 this 在 5 個常用場景中的表現以及應對策略。

1. 普通呼叫

下面範例示範了函數參考和函數呼叫對 this 的影響。

var obj = {  //父对象
    name : "父对象obj",
    func : function () {
        return this;
    }
}
obj.sub_obj = {  //子对象
    name : "子对象sub_obj",
    func : obj.func
}
var who = obj.sub_obj.func();
console.log(who.name);  //返回“子对象sub_obj”,说明this代表sub_obj

如果把子物件 sub_obj 的 func 改為函數呼叫。

obj.sub_obj = {
    name : "子对象sub_obj",
    func : obj.func()  //调用父对象obj的方法func
}

則函數中的 this 所代表的是定義函數時所在的父物件 obj。

var who = obj.sub_obj.func;
console.log(who.name);  //返回“父对象obj”,说明this代表父对象obj

2. 實例化

使用 new 指令呼叫函數時,this 總是指涉實例物件。

var obj = {};
obj.func = function () {
    if (this == obj) console.log("this = obj");
    else if (this == window) console.log("this = window");
    else if (this.contructor == arguments.callee) console.log("this = 实例对象");
}
new obj.func;  //实例化

3. 動態呼叫

使用 call 和 apply 可以強制改變 this,使其指向參數物件。

function func () {
    //如果this的构造函数等于当前函数,则表示this为实例对象
    if (this.contructor == arguments.callee) console.log("this = 实例对象");
    //如果this等于window,则表示this为window对象
    else if (this == window) console.log("this = window对象");
    //如果this为其他对象,则表示this为其他对象
    else console.log("this == 其他对象 \n this.constructor =" + this.constructor);
}
func();  //this指向window对象
new func();  //this指向实例对象
cunc.call(1);  //this指向数值对象

在上面範例中,直接呼叫 func() 時,this 代表 window 物件。當使用 new 指令呼叫函數時,將會建立一個新的實例對象,this 就指向這個新建立的實例物件。

使用call() 方法執行函數func() 時,由於call() 方法的參數值為數字1,則JavaScript 引擎會將數字1 強制封裝為數值對象,此時this 就會指向這個數值物件。

4. 事件處理

在事件處理函數匯總,this 總是指向觸發該事件的物件。

<input type="button" value="测试按钮" />
<script>
    var button = document.getElementsByTagName("put")[0];
    var obj = {};
    obj.func = function () {
        if (this == obj) console.log("this = obj");
        if (this == window) console.log("this = window");
        if (this == button) console.log("this = button");
    }
    button.onclick = obj.func;
</script>

在上面程式碼中,func() 所包含的this 不再指向物件obj,而是指向按鈕button,因為func() 是被傳遞給按鈕的事件處理函數之後才被呼叫執行的。

如果使用DOM2 等級標準註冊事件處理函數,程式如下:

if (window.attachEvent) {  //兼容IE模型
    button.attachEvent("onclick", obj.func);
} else {  //兼容DOM标准模型
    button.addEventListener("click", obj.func, true);
}

在IE 瀏覽器中,this 指向window 物件和button 對象,而在DOM 標準的瀏覽器中僅指向button 對象。因為,在 IE 瀏覽器中,attachEvent() 是 window 物件的方法,當呼叫該方法時,this 會指向 window 物件。

為了解決瀏覽器相容性問題,可以呼叫 call() 或 apply() 方法強制在物件 obj 身上執行方法 func(),避免出現不同的瀏覽器對 this 解析不同的問題。

if (window.attachEvent) {
    button.attachEvent("onclick", function () {  //用闭包封装call()方法强制执行func()
        obj.func.call(obj);
    });
} else {
    button.attachEventListener("onclick", function () {
        obj.func.call(obj);
    }, true);
}

當再次執行時,func() 中包含的 this 總是指向物件 obj。

5. 定時器

使用定時器呼叫函數。

var obj = {};
obj.func = function () {
    if (this == obj) console.log("this = obj");
    else if (this == window) console.log("this = window对象");
    else if (this.constructor == arguments.callee) console.log("this = 实例对象");
    else console.log("this == 其他对象 \n this.constructor =" + this.constructor);
}
setTimeOut(obj.func, 100);

在 IE 中 this 指向 window 物件和 button 對象,具體原因與上面講解的 attachEvent() 方法相同。在符合 DOM 標準的瀏覽器中,this 指向 window 對象,而不是 button 物件。

因為方法 setTimeOut() 是在全域作用域中被執行的,所以 this 指向 window 物件。若要解決瀏覽器相容性問題,可以使用 call 或 apply 方法來實作。

setTimeOut (function () {
    obj.func.call(obj);
}, 100);

【推薦學習:javascript進階教學

以上是javascriptthis是什麼意思的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn