再一次進行對this知識點的復習,每一次都是溫故知新的過程。
這次對于this的學習基于《你所不知道的JavaScript》這本書,算是對于書中的知識做一個總結。
首先要明確的是一般情況下,this不是函數(shù)被定義時綁定,而是函數(shù)被調用時被綁定
那么函數(shù)中的this有四種綁定方式:
1. 默認綁定
直接調用函數(shù),使用不帶任何修飾的函數(shù)進行調用,只能使用默認綁定,無法應用其它規(guī)則,代碼如下:
function foo() {
console.log(this.a);
}
var a = 1;
foo() // 1
2. 隱式綁定
函數(shù)被調用時有上下文對象,那么this會綁定這個上下文對象,代碼如下:
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
var a = 1;
obj.foo() // 2
其實不能講foo這個函數(shù)屬于obj對象,但是foo函數(shù)被調用時的落腳點的確是指向obj對象,當函數(shù)引用有上下文對象時,隱式綁定就會把函數(shù)調用中的this綁定到這個上下文對象;
對象屬性引用鏈中只有最頂層或者說最后一層會影響調用位置
var foo = function () {
console.log(this.a)
}
var obj2 = {
a: 2
foo: foo
}
var obj1 = {
a: 1
obj2: obj2
}
obj1.obj2.foo() // 2
隱式丟失
對于應用隱式綁定方式綁定this經常導致的一個情況是隱式丟失this
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
var bar = obj.foo;
var a = 'global';
bar() // 'global'
針對這種情況,雖然bar是obj.foo的一個引用,但是實際上它引用的是foo函數(shù)本身,此時bar()其實是一個不帶任何修飾的函數(shù)調用,應用了默認綁定;
3. 硬綁定
使用call,apply或者bind,在調用函數(shù)的時候直接指定上下文對象,那么函數(shù)中的this會綁定到傳入的對象,代碼如下:
function foo() {
console.log(this.a);
}
var obj = {
a: 1
}
foo.apply(obj) // 1
4. new綁定
使用new調用某個構造函數(shù),代碼如下:
function Foo(a) {
this.a = a;
console.log(this.a);
}
var obj = new Foo(2);
console.log(obj.a) // 2