this 的工做原理

this 的工做原理

JavaScript 有一套徹底不一樣於其它語言的對 this 的處理機制。
種不一樣的狀況下 ,this 指向的各不相同。數組

全局範圍內

this;

當在所有範圍內使用 this,它將會指向全局對象。瀏覽器

譯者注瀏覽器中運行的 JavaScript 腳本,這個全局對象是 window閉包

函數調用

foo();

這裏 this 也會指向全局對象。app

ES5 注意: 在嚴格模式下(strict mode),不存在全局變量。
這種狀況下 this 將會是 undefined函數

方法調用

test.foo();

這個例子中,this 指向 test 對象。this

調用構造函數

new foo();

若是函數傾向於和 new 關鍵詞一塊使用,則咱們稱這個函數是 構造函數
在函數內部,this 指向新建立的對象。prototype

顯式的設置 this

function foo(a, b, c) {}

var bar = {};
foo.apply(bar, [1, 2, 3]); // 數組將會被擴展,以下所示
foo.call(bar, 1, 2, 3); // 傳遞到foo的參數是:a = 1, b = 2, c = 3

當使用 Function.prototype 上的 call 或者 apply 方法時,函數內的 this 將會被
顯式設置爲函數調用的第一個參數。設計

所以函數調用的規則在上例中已經不適用了,在foo 函數內 this 被設置成了 barcode

注意: 在對象的字面聲明語法中,this 不能用來指向對象自己。
所以 var obj = {me: this} 中的 me 不會指向 obj,由於 this 只可能出如今上述的五種狀況中。
譯者注這個例子中,若是是在瀏覽器中運行,obj.me 等於 window 對象。對象

常見誤解

儘管大部分的狀況都說的過去,不過第一個規則(譯者注這裏指的應該是第二個規則,也就是直接調用函數時,this 指向全局對象)
被認爲是JavaScript語言另外一個錯誤設計的地方,由於它歷來就沒有實際的用途。

Foo.method = function() {
    function test() {
        // this 將會被設置爲全局對象(譯者注:瀏覽器環境中也就是 window 對象)
    }
    test();
}

一個常見的誤解是 test 中的 this 將會指向 Foo 對象,實際上不是這樣子的。

爲了在 test 中獲取對 Foo 對象的引用,咱們須要在 method 函數內部建立一個局部變量指向 Foo 對象。

Foo.method = function() {
    var that = this;
    function test() {
        // 使用 that 來指向 Foo 對象
    }
    test();
}

that 只是咱們隨意起的名字,不過這個名字被普遍的用來指向外部的 this 對象。
閉包 一節,咱們能夠看到 that 能夠做爲參數傳遞。

方法的賦值表達式

另外一個看起來奇怪的地方是函數別名,也就是將一個方法賦值給一個變量。

var test = someObject.methodTest;
test();

上例中,test 就像一個普通的函數被調用;所以,函數內的 this 將再也不被指向到 someObject 對象。

雖然 this 的晚綁定特性彷佛並不友好,可是這確實基於原型繼承賴以生存的土壤。

function Foo() {}
Foo.prototype.method = function() {};

function Bar() {}
Bar.prototype = Foo.prototype;

new Bar().method();

method 被調用時,this 將會指向 Bar 的實例對象。

相關文章
相關標籤/搜索