再说js中this的指向

再说js中this的指向

js中,this的指向一直是一个难点,新手很容易搞糊涂,其实只需要记住一个规则就行了,规则先不说,看了下面的例子你就明白了:

var obj = {
  a: 100,
  b: function() {
    console.log(this)
  }
}
obj.b();// 1. this 指向obj

上面的代码,执行obj.b()后,打印出了obj对象,{a: 100, b: ƒ}证明此时this的指向时obj对象,这个很好理解。

加以修改:

var obj = {
  a: 100,
  b: function() {
    console.log(this)
  }
}
var some = obj.b;
some();// 2. this 指向window,因为some的执行上下文是window对象。

这段代码,将obj.b赋值给一个some变量,现在some变量就 变成了一个可执行函数,执行一下结果看到,this打印的是window对象。Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}这就尴尬了,为什么函数里面打印的this变了呢?这是因为,js执行的时候,this的指向是指向它执行时的上下文的,我们看,上面代码,首先是定义了一个some变量,注意这个some变量是定义在window对象上的,此时some的执行上下文就是window,再把obj.b赋予给了some,此时some变成了一个函数,所以再执行some时,函数内的执行上下文,就是some所在的上下文,也就是window了。

不信邪了,那如果我不在window对象上定义一个some呢?此时this又指向哪里呢?

var obj = {
  a: 100,
  b: function() {
    console.log(this)
  }
}
var oth = {
  some: obj.b
}
oth.some() 

现在做了什么操作?我不再把some定义在window里面了,我把some定义在了一个oth对象里面,同样将ob j.b赋值给some,现在指向some的话,是什么结果呢?{some: ƒ}可见,this指向了oth对象,好像明白了点什么,根据上面的分析,this指向它执行时的上下文,它执行时,是作为oth的some字段的属性执行的,所以它的this就指向了oth对象。

明白了,以上就是js语言this的机制。感觉有点怪怪的,如果我每次调用,总是想让this指向最原始的对象呢?也可以,用call或者apply就可以实现:

var obj = {
  a: 100,
  b: function() {
    console.log(this)
  }
}
obj.b();// 1. this 指向obj
var some = obj.b;
some();// 2. this 指向window,因为some的执行上下文是window对象。

var oth = {
  some: obj.b
}
oth.some(); // 3. this 指向oth,因为some的执行上下文是oth对象。

// 这是js语言的机制,this总是 指向具体调用时的执行上下文。
// call 和 apply能改变这种机制,从而实现手动更改this的指向:

// 2. 手动将this指向obj
some.call(obj)
// 3. 手动将this指向obj
oth.some.call(obj)

指向上面代码,就可以看出,上面的this,通过call函数,都被手动指向到obj中去了。apply也有同样功能,有一些细微差别,就不细说了。