阅读 8

this 在 JavaScript 中的指向及特殊的箭头函数

----欢迎查看我的博客----

this 关键字

  this是Javascript语言的一个关键字。JavaScript 是一种脚本语言,因此被很多人认为是简单易学的。然而情况恰恰相反,JavaScript 支持函数式编程、闭包、基于原型的继承等高级功能,大家经常会困惑,this究竟指向谁,在这里先灌输一个概念别管this是谁,this 谁调指谁,没人调指window(global)

image

谁调就指谁

  this谁调指谁。例:

function a(){
	this.b = 1
}
var c = new a();
console.info(c,c.b)//a:{b: 1}  1
复制代码

  上面这行代码已经诠释了。此时的this指向对象c,因为我们答应的是c.b,c调用了b谁调指谁没毛病。

没人掉指global,换句话说还是谁调指谁

  没人调用this会指向global,尝试查看下面两个代码片段

function a(){
	this.b = 1;
}
a();
console.log(window.b) //1
复制代码
this.b = 1;
console.log(window.b) //1
复制代码

  上面代码也诠释了this的指向问题。window调用b,所以this指向是window。

箭头函数

  众所周知,箭头函数是es6的新语法,其实官网说的也很明白。它不能作为构造函数,例:

var a = ()=>{
	this.b = 1
}
var c = new a() //报错:Uncaught TypeError: a is not a constructor
console.info(c.b)
复制代码

  这就是为什么箭头函数不存在this的指向变更的本质。如果这里换成普通的function就是可以成立的。

总结

1.箭头函数的this绑定看的是this所在的函数定义在哪个对象下,绑定到哪个对象则this就指向哪个对象

2.如果有对象嵌套的情况,则this绑定到最近的一层对象上。

  所以我们常说箭头函数的this问题,实际是比较箭头函数和普通function的方法。

setTimeout & setInterval

  setTimeOut:“超时调用的代码都是在全局作用域中执行的,因此函数中this的值在非严格模式下指向window对象,在严格模式下是undefined”。在这里,我们只讨论非严格模式。

看看下面俩个代码片段:

箭头函数版本

function foo() {
  this.b = 1
  setTimeout(() => {
    console.log('id:', this.b); //id: 1
  }, 100);
}
var a = new foo()
console.log(a.b) // 1
复制代码

function版本

function foo() {
  this.b = 1
  setTimeout(function() {
    console.log('id:', this.b); //id: undefined
  }, 100);
}
var a = new foo()
console.log(a.b) //1
复制代码

那我们就想获取这个b用function版本怎么办呢?我们来尝试一下

改良版

function foo() {
  var self = this;
  self.b = 1
  setTimeout(function() {
    console.log('id:', self.b); //id: 1
  }, 100);
}
var a = new foo()
复制代码

好的,达成目标~

结语

  经过上面这番折腾,想必大家对这个this已经比较明白了。反正就是那句话,谁调指谁 ! 好了今天就到这里,去抽一根烟。

评论