js函式中的this指向

愛抽菸的王源發表於2023-02-02

寫程式碼的時候遇到這個問題了,在這裡複習一下

  1. 非箭頭函式
    非箭頭函式的this指向比較好理解,就是呼叫這個函式的物件,舉個例子:
var obj = {
    foo: {
        bar: 3,
        foo:{
            bar: 4,
            foo: function a() { console.log(this.bar) },
        },
    },
    bar: 2
};

var foo = obj.foo.foo.foo;
var bar = 1;

obj.foo.foo.foo(); //由obj.foo.foo呼叫,所以此時this指向它,所以列印的this.a為4
foo(); //由window呼叫,所以this指向window,列印1
  1. 箭頭函式
    箭頭函式的this指向,網上看到有一種說話是:箭頭函式的this指向定義他的物件,這樣理解是錯誤的。。。
    嚴格來講應該是:箭頭函式的this指向定義它的上下文物件,更通俗一點來說就是指向定義箭頭函式的那個形成函式作用域的函式所在物件(個人理解,有疑問的話可以在評論區討論一下)
    舉個例子
var obj = {
    foo: {
        bar: 3,
        foo() {
            var bar = 4;
            return () => { console.log(this.bar) };
        },
    },
    bar: 2
};

var foo = obj.foo.foo;
var bar = 1;
obj.foo.foo()() // 此時this指向obj.foo物件,列印3
foo()()  // 此時this指向window,列印1

需要注意的是,執行函式的時候箭頭函式才被定義,所以下面這個栗子列印結果才會不一樣
下面這段程式碼最後列印出來都是3

var obj = {
    foo: {
        bar: 3,
        foo() {
            var bar = 4;
            return () => { console.log(this.bar) };
        },
    },
    bar: 2
};

var foo = obj.foo.foo(); // 改了這裡
var bar = 1;
obj.foo.foo()() // 3
foo() // 3



最後,看一下把箭頭函式換成普通函式的寫法

var obj = {
    foo: {
        bar: 3,
        foo() {
            var bar = 4;
            return function() { console.log(this.bar) };
        },
    },
    bar: 2
};

var foo = obj.foo.foo;
var bar = 1;

obj.foo.foo()() // 1
foo()() // 1

總之就是,使用箭頭函式的this需要考慮它被定義的時候所在函式作用域的this,使用普通函式只用看誰呼叫了它。

相關文章