this 指向问题

# 专题总结:this 指向问题

拿到 字节跳动实习生 offer 总结

回馈分享一波自己的知识点总结

希望读者依此构建自己的知识树(思维导图)

偷懒一下:可参考我自己总结思维导图 : 点这里

附带:高频面试题积累文档。 来自于(学长、牛客网等平台)

自己开发的博客地址:zxinc520.com

github 地址: 点击

此篇 js - 【this 指向问题】 知识点: 全部弄懂了,面试很容易。

# 一、this 的四条绑定规则

  1. 默认绑定

    • 独立函数调用时,this 指向全局对象(window),如果使用严格模式,那么全局对象无法使用默认绑定, this 绑定至 undefined。
  2. 隐式绑定

    • 函数 this 是指向调用者 (隐式指向)

      function foo() {
        console.log(this.a);
      }
      var obj = {
        a: 2,
        foo: foo,
      };
      obj.foo(); // 2
      • obj1.obj2.foo (); //foo 中的 this 与 obj2 绑定
    • 问题:隐式丢失

      • 描述:隐式丢失指的是函数中的 this 丢失绑定对象,即它会应用第 1 条的默认绑定规则,从而将 this 绑定到全局对象或者 undefined 上,取决于是否在严格模式下运行。
      • 以下情况会发生隐式丢失
        1. 绑定至上下文对象的函数被赋值给一个新的函数,然后调用这个新的函数时
        2. 传入回调函数时
  3. 显式绑定

    • 显式绑定的核心是 JavaScript 内置的 call (…) 和 apply (…) 方法,call 和 apply bind 的 this 第一个参数 (显示指向)
  4. new 绑定

    • 构造函数的 this 是 new 之后的新对象 (构造器)

# 二、call bind apply

改变函数执行时的上下文(改变函数运行时的 this 指向)

# 2.1、apply

  • 第二个参数为数组

  • 自定义实现

    // 自定义apply函数
    Function.prototype.apply1 = function (obj, arg) {
      //context为null或者是undefined时,设置默认值
      if (!obj) {
        obj = typeof window === "undefined" ? global : window;
      }
      obj.fn = this;
      let result = null;
      //undefined 或者 是 null 不是 Iterator 对象,不能被 ...
      if (arg === undefined || arg === null) {
        result = obj.fn(arg);
      } else {
        result = obj.fn(...arg);
      }
      delete obj.fn;
      return result;
    };

# 2.2、call

  • 第二个参数为参数列表

  • 自定义实现

    Function.prototype.call1 = function (obj, ...arg) {
      if (!obj) {
        obj = typeof window === "undefined" ? global : window;
      }
      obj.fn = this;
      let result = null;
      result = obj.fn(...arg);
      delete obj.fn;
      return result;
    };

# 2.3、bind

  • 特点

    • 返回一个函数
    • 可以传入参数(使用 bind 时和 bind 新生成的函数都可以传参)
    • 当 bind 返回的函数作为构造函数的时候,bind 时指定的 this 值会失效,但传入的参数依然生效
  • 注意:bind 这个方法在 IE6~8 下不兼容

  • 自定义实现

    Function.prototype.bind1 = function (obj, ...arg) {
      if (!obj) {
        obj = typeof window === "undefined" ? global : window;
      }
      let self = this;
      let args = arg;
      function f() {}
      f.prototype = this.prototype;
      let bound = function () {
        let res = [...args, ...arguments];
        let _this = this instanceof f ? this : obj;
        return self.apply(_this, res);
      };
      bound.prototype = new f();
      return bound;
    };

# 2.4、区别

call 和 apply 改变了函数的 this 上下文后便执行该函数,而 bind 则是返回改变了上下文后的一个函数。

# 三、相关题目

  1. 怎么利用 call、apply 来求一个数组中最大或者最小值

    let arr = [1, 2, 19, 6];
    Math.max.call(null, ...arr);
    Math.max.apply(null, arr);
    var fn = Math.max.bind(null, ...arr);
    fn();
  2. 如何利用 call、apply 来做继承

  3. apply、call、bind 的区别和主要应用场景

    1. 将类数组 / 含有 length 属性的对象转化为数组
    2. 求数组中的最大和最小值
    3. 数组追加
    4. 利用 call 和 apply 做继承
    5. 判断变量类型
Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2015-2021 zhou chen
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信