你不知道的this(3)

2020-10-23 17:14:03 浏览数 (1)

this 补充

任何足够先进的技术都和魔法无异

普通函数和箭头函数下的 this

代码语言:javascript复制
var obj = {
  id: "awesome",
  cool: function coolFn() {
    console.log(this.id);
  },
};
var id = "not awesome";
obj.cool();
setTimeout(obj.cool, 100); // not awesome

我们可以看到,我们预期这里会输出awesome,结果打印结果显示我们丢失了this的绑定,解决这个问题的办法有很多种,最常见的就是 var self = this

self

代码语言:javascript复制
var obj = {
  count: 0,
  cool: function coolFn() {
    var self = this;
    if (self.count < 1) {
      setTimeout(function timer() {
        self.count  ;
        console.log("awesome?");
      }, 100);
    }
  },
};
obj.cool(); // awesome

var self = this这种解决方案可以圆满解决理解和正确使用this绑定的问题,并且没有把问题复杂化,它使用的是我们常见的工具:词法作用域

this只是一个可以通过词法作用域和闭包进行引用的标识符,不关心this绑定的过程发生了什么

人们不喜欢写冗长的东西,尤其是一遍一遍地写。因此ES6的一个初衷就是帮助人们减少重复的场景,事实上包括修复某些习惯用法的问题,this就是其中一个。

箭头函数下的 this

ES6中的箭头函数引入了一个叫作this词法的行为:

代码语言:javascript复制
var obj = {
  count: 0,
  cool: function coolFn() {
    if(this.count < 1) {
      setTimeout(() => {
        this.count  ;
        console.log('awesome');
      }, 100);
    }
  }
}

简单来说,箭头函数在涉及this绑定时的行为和普通函数的行为完全不一样,它完全摒弃了所有普通 this的绑定规则,取而代之的是用当前的词法作用域覆盖了this本来的值。

因此,这个代码片段中的箭头函数并非是以某种不可预测的方式同所属的this进行了解绑定,而只是继承了 cool 函数的 this绑定(因此调用它不会出错)

除了可以少写点代码,箭头函数将程序员们经常犯的一个错误给标准化了,也就是混淆了this绑定规则和词法作用域规则。

箭头函数的弊端

  • 我们为什么要自找麻烦使用this风格的代码模式呢?把它和词法作用域结合在一起非常让人头疼。在代码中使用两种风格的其中一种是非常自然的事情,但是不要将两种风格混在一起使用
  • 箭头函数是匿名而非具名的,具体的弊端可见作用域那块的详细描述

更好的办法

代码语言:javascript复制
var obj = {
  count: 0,
  cool: function coolFn() {
    if(this.count < 1) {
      setTimeout(function timer() {
        this.count  ;
        console.log('more awesome');
      }.bind(this), 100);
    }
  }
}

0 人点赞