天天看點

JavaScript函數中this的4種綁定政策

JavaScript函數中this的4種綁定政策

今天,我們進行對this知識點的複習,每一次都是溫故知新的過程。

這次對于this的學習是基于《你所不知道的JavaScript》這本書,算是對于書中的知識做一個總結。

如果你有興趣,也可以通過下面的連接配接精選購買此書,也算是對我和對作者的一種支援,在此,非常感謝。

首先,要明确的是一般情況下,this不是函數被定義時綁定,而是函數被調用時被綁定  

那麼函數中的this有四種綁定方式:

1、預設綁定

直接調用函數,使用不帶任何修飾的函數進行調用,隻能使用預設綁定,無法應用其它規則,代碼如下:

function foo() {
  console.log(this.a);
}
var a = 1;
foo() // 1      

2、隐式綁定

函數被調用時有上下文對象,那麼this會綁定這個上下文對象,代碼如下:

function foo() {
  console.log(this.a);
}
var obj = {
  a: 2,
  foo: foo
}
var a = 1;
obj.foo() // 2      

其實不能講foo這個函數屬于obj對象,但是foo函數被調用時的落腳點的确是指向obj對象,當函數引用有上下文對象時,隐式綁定就會把函數調用中的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函數本身,此時bar()其實是一個不帶任何修飾的函數調用,應用了預設綁定;

3、硬綁定

使用call,apply或者bind,在調用函數的時候直接指定上下文對象,那麼函數中的this會綁定到傳入的對象,代碼如下:

function foo() {
  console.log(this.a);
}
var obj = {
  a: 1
}
foo.apply(obj) // 1      

4、new綁定

使用new調用某個構造函數,代碼如下:

function Foo(a) {
  this.a = a;
  console.log(this.a);
}
var obj = new Foo(2);
console.log(obj.a) // 2      

繼續閱讀