JavaScript 系列之 this(二)

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战javascript

2、改变 this 的指向

var name = "windowsName";
var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },

  func2: function () {
    setTimeout(function () {
      this.func1();
    }, 100);
  },
};
a.func2(); // this.func1 is not a function
复制代码

在不使用箭头函数的状况下,是会报错的,由于最后调用 setTimeout 的对象是 window,可是在 window 中并无 func1 函数。前端

2.1 使用 ES6 的箭头函数

箭头函数中没有 this 绑定,必须经过查找做用域链来决定其值,若是箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,不然,this 为 undefined。java

var name = "windowsName";
var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },

  func2: function () {
    setTimeout(() => {
      this.func1();
    }, 100);
  },
};
a.func2(); // Cherry
复制代码

2.2 在函数内部使用 _this = this

若是不使用 ES6,那么这种方式应该是最简单的不会出错的方式了,咱们是先将调用这个函数的对象保存在变量 _this 中,而后在函数中使用这个 _this,这样 _this 就不会改变了。react

var name = "windowsName";
var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },

  func2: function () {
    var _this = this;
    setTimeout(function () {
      _this.func1();
    }, 100);
  },
};
a.func2(); // Cherry
复制代码

这个例子中,在 func2 中,首先设置 var _this = this;,这里的 this 是调用 func2 的对象 a,为了防止在 func2 中的 setTimeout 被 window 调用而致使的在 setTimeout 中的 this 为 window。咱们将 this(指向变量 a) 赋值给一个变量 _this,这样,在 func2 中咱们使用 _this 就是指向对象 a 了。面试

2.3 使用 call、apply、bind

一、使用 callwindows

var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },

  func2: function () {
    setTimeout(
      function () {
        this.func1();
      }.call(a),
      100
    );
  },
};
a.func2(); // Cherry
复制代码

二、使用 apply数组

var a = {
  name: "Cherry",
  
  func1: function () {
    console.log(this.name);
  },
  
  func2: function () {
    setTimeout(
      function () {
        this.func1();
      }.apply(a),
      100
    );
  },
};
a.func2(); // Cherry
复制代码

三、使用 bind性能优化

var a = {
  name: "Cherry",

  func1: function () {
    console.log(this.name);
  },
  
  func2: function () {
    setTimeout(
      function () {
        this.func1();
      }.bind(a)(),
      100
    );
  },
};
a.func2(); // Cherry
复制代码

2.4 new 实例化一个对象

3、对 call 和 apply 和 bind 分析

3.1 call 和 apply 的区别

call 和 apply 都是为了解决改变 this 的指向。做用都是相同的,只是传参的方式不一样。markdown

除了第一个参数外,call 能够接收一个参数列表,apply 只接受一个参数数组。app

在 fun 函数运行时指定的 this 值:

  • fun.call(thisArg, arg1, arg2, ...)
  • func.apply(thisArg, [argsArray])
var a = {
  value: 1,
};
function getValue(name, age) {
  console.log(name);
  console.log(age);
  console.log(this.value);
}
getValue.call(a, "yck", "24"); // yck 24 1
getValue.apply(a, ["yck", "24"]); // yck 24 1
复制代码

3.2 bind

bind() 方法建立一个新的函数, 当被调用时,将其 this 关键字设置为提供的值,在调用新函数时,在任何提供以前提供一个给定的参数序列。

var a = {
  name: "Cherry",
  fn: function (a, b) {
    console.log(a + b);
  },
};
var b = a.fn;
b.bind(a, 1, 2)(); // 3
复制代码

相关文章

相关文章
相关标签/搜索