前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[ JavaScript ] 执行函数中改变 this 的指向以及方法

[ JavaScript ] 执行函数中改变 this 的指向以及方法

原创
作者头像
GavinUI
发布2021-04-07 11:10:32
1.1K0
发布2021-04-07 11:10:32
举报
文章被收录于专栏:GavinUI

执行函数中改变 this 的指向以及方法

最开始还想把这个笔记名字改成 bind apply call 之前的区别,但是,想了想记录笔记还是要从原因开始,再到为什么再到怎么做。所以,还是改成 执行函数中改变 this 的指向以及方法。

改变 this 的指向的方法和执行

bind,apply,call 都是执行函数时,用来改变 this 的指向。另外,apply、call 是立即执行,而 bind 是调用的时候才执行。

为什么需要改变这个 this 的指向

需要改变这个 this 的指向,是因为原来的 this 被污染了,需要重新再进行 this 指向,因为,this 指向的是被调用的父级作用域,而如果函数在另一个函数里面执行的时候,那么,这个 this 的指向的就是这个函数,而不是那个被执行函数原来的那个作用域。

举例:

代码语言:txt
复制
const fighter = {
  model: '700',
  fire: function (res) {
    console.log(this.model);
    console.log(res);
  },
};
setTimeout(function () {
  fighter.fire();
}, 1000);

// underined

此时,setTimeout() 里面的函数 this 的指向是指向了 window,而 fighter.fire() 这个函数的执行 this是需要指向这个 fighter 的。所以,执行的时候就会 输出 undefined 。因为,在 setTimeout 这个域下找不到这个 model 的参数。这个就需要把 这个 this 的指向改成指向 fighter 这个对象。以下是改变 this 指向的方法。

使用 call 改变 this 指向

call的第一个参数是 this 的指向,后面是一个传入参数的列表。

代码语言:txt
复制
const fighter = {
  model: '700',
  fire: function (args1, args2) {
    console.log(this.model);
    console.log(args1);
    console.log(args2);
  },
};
setTimeout(function () {
  fighter.fire.call(fighter, 'fire', '700');
}, 1000);

// 700 
// fire 
// 700

第一个参数是改变 this 的指向, 第二个以后的参数是分别进行传参。

使用 apply 改变 this 指向

使用 apply 改变 this 指向和 call 改变指向大致上方法是一样的,唯一有不同的就是传参是以单个参数(数组)进行传递,如下图:

代码语言:txt
复制
const fighter = {
  model: '700',
  fire: function (args1) {
    console.log(this.model);
    console.log(args1);
  },
};
let plane = fighter.fire;
setTimeout(function () {
  plane.apply(fighter, ['1']);
}, 1000);
// 700 
// 1

使用 bind 改变 this 指向

上面已经提到过,bind 的执行和前面的 call 和 apply 的执行是不一样的,call 和 apply 是立即执行一次。而 bind 是手动执行同时 bind 是永久改变 this 的指向

代码语言:txt
复制
const fighter = {
  model: '700',
  fire: function (args1 = 'none') {
    console.log(this.model);
    console.log(args1);
  },
};
let plane = fighter.fire;
setTimeout(function () {
  plane.bind(fighter, ['fire'])();
  fighter.fire('fire-2');
}, 1000);

// output
// 700
// ['fire']
// 700
// fire-2

像这个例子,plane.bind(fighter, 'fire') 是需要手动执行才会触发,这是第一点。另一点是下面再次执行 fighter.fire('fire-2') 的时候,由于,前面已经使用过 bind 改变了 this 的指向。这个时候再次调用 fire 这个函数,就不需要再改变 this 的指向了,直接执行就可以。

一些通用的使用场景

判断数组的最大,最小值

判断一个数组的最大最小值,最简单的方法就是

代码语言:txt
复制
const num = [1, 2, 6, 4, 8, 3, 78, 10];
console.log(Math.max(1, 2, 6, 4, 8, 3, 78, 10));

但是,Math.max 是不支持接受一个数组参数的,那么就需要利用 apply 的一个特性,就是将数组参数依次传递的特性,再执行。

代码语言:txt
复制
const num = [1, 2, 6, 4, 8, 3, 78, 10];
console.log(Math.max.apply(null, num));
console.log(Math.min.apply(null, num));

第一个参数传递 null ,因为没有需要用到这个 this ,所以, 只要这个利用这个函数执行就可以。

可以理解为 最终的执行是相当于

代码语言:txt
复制
Math.max(1, 2, 6, 4, 8, 3, 78, 10);
Math.min(1, 2, 6, 4, 8, 3, 78, 10);
实现类的继承
代码语言:txt
复制
function Plane(num) {
  this.engine = num;
  this.land = function () {
    console.log(this.engine);
  }
};
function Fighter(num) {
  Plane.call(this, num);
};
const plane_1 = new Fighter('666');
plane_1.land();

这里在 Fighter 中 执行 Plane 同时 将 Plane 的指向 ,指向 Fighter 。那么,Plane 的 this 就指向了 fighter ,更简单的理解就是,这个时候 Plane 的函数体放在了 Fighter 中,也就是继承。

伪数组转换成数组
代码语言:txt
复制
const obj = { 0: '12', 1: '2', length: 2 };

const array_1 = Array.prototype.slice.call(obj);
console.log(array_1);

const array_2 = [].slice.call(obj);
console.log(array_2);
保存 this

下面这一段是 使用 一个 _that 保存了 this;

代码语言:txt
复制
const obj = {
  num: 123,
  getNum: function () {
    const _that = this;
    setTimeout(function () { 
      console.log(_that.num);
    }, 1000);
  },
};
// output
// 123

等同于用 bind 改变 this 的指向的写法:

代码语言:txt
复制
const obj_2 = {
  num: 123,
  getNum: function () {
    setTimeout(function () {
      console.log(this.num);
    }.bind(this), 1000);
  },
};
obj_2.getNum();

// output
// 123

以上是我对函数改变 this 指向方法的理解。

卧槽,今天的咖啡店来了一个漂亮的小姐姐,肤白貌美大长腿,emmmm思考一下怎么要微信好。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 执行函数中改变 this 的指向以及方法
    • 改变 this 的指向的方法和执行
      • 为什么需要改变这个 this 的指向
        • 使用 call 改变 this 指向
          • 使用 apply 改变 this 指向
            • 使用 bind 改变 this 指向
              • 一些通用的使用场景
                • 判断数组的最大,最小值
                • 实现类的继承
                • 伪数组转换成数组
                • 保存 this
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档