JavaScript this

了解他的綁定規則及工作機制,知道在一個函數中它等同於什麼或者說指向什麼。

This 是什?

  • this 是JavaScript的一個關鍵字
  • this 是function執行時,自動生成的一個內部物件
  • 隨著function執行場合不同,this所指向的值也會有所不同
  • 大多數情況下,this代表的就是呼叫的function的物件 (Owner Object og the function)

默認綁定

this指向了全域

1
2
3
4
5
6
7
8
// 默認綁定
function fn() {
console.log(this);
}

// If called in browser:
fn(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}
console.log(fn === window.fn); // -> true

隱式綁定「上下文對象」

obj1.foo() 調用時,綁定到obj1
obj2.foo() 調用時,綁定到obj2

1
2
3
4
5
6
7
8
9
10
11
12
13
function foo() {
console.log(this.a);
}
let obj1 = {
a: 1,
foo,
};
let obj2 = {
a: 2,
foo,
}
obj1.foo(); // 輸出 1
obj2.foo(); // 輸出 2

顯示綁定 「apply、call、bind」

call()apply()其實做的事情是一樣的,差別在於接受的參數不太一樣。

  • call(this, arg1, arg2, …)
  • apply(this, [arg1, arg2, …])
    bind(),則是創建一個新的包裝函數,並且返回而不是立即執行。
  • bind(this, arg1, arg2)
1
2
3
4
5
6
7
8
9
10
11
12
13
function fn() {
console.log(this);
}

var obj = {
value: 5
};

var boundFn = fn.bind(obj);

boundFn(); // -> { value: 5 }
fn.call(obj); // -> { value: 5 }
fn.apply(obj); // -> { value: 5 }

new 綁定

使用 new 關鍵字時,函數內部是由JavaScript創建的全新對象。

1
2
3
4
5
6
7
8
9
function ConstructorExample() {
console.log(this);
this.value = 10;
console.log(this);
}

new ConstructorExample();
// -> ConstructorExample {}
// -> ConstructorExample { value: 10 }

優先級

下面說明「顯示綁定」優先於「隱式綁定」

1
2
3
4
5
6
7
8
9
// 1
var obj = {
value: 5,
printThis: function() {
console.log(this.value);
}
};
obj.printThis(); // -> { value: 5, printThis: ƒ }
obj.printThis.call({value:10});

下面說明「new綁定」優先於「顯示綁定」

1
2
3
4
5
6
7
8
9
10
function foo(a) {
this.a = a;
}
let obj1 = {};
let bar = foo.bind(obj1);
bar(2);
console.log(obj1); // 输出 {a:2}
let obj2 = new bar(3);
console.log(obj1); // 输出 {a:2}
console.log(obj2); // 输出 foo { a: 3 }

而默認綁定是優先級最低的
「new 綁定」 > 「顯示綁定」 > 「隱式綁定」 > 「默認綁定」

原文以及參考

The Complete Rules to ‘this’
加深对 JavaScript This 的理解
What’s THIS in JavaScript ? [上]

0%