this、作用域、闭包

66 阅读2分钟

作用域 + 上下文

作用域链 静态

// 1. 函数默认提升
// 2. var变量可以提升
// 3. 作用域链式方式从上到下 => 限制在函数内部

// #########

function teacher() {
  let d = "yy";
  console.log(d);
}
if (true) {
  let e = 111;
  var f = 222;
  console.log(e, f);
}
console.log("d->", d);
console.log("e->", e);
console.log("f->", f);

// 1.具备不同的独立作用域范围 => 追问:函数的作用域 => 块级作用域
// 2.改用var声明,只有function可以隔离作用域 => 函数的模块隔离 =》 js module => 模块化 =》 IIFE

this 上下文 context

  • 我家门前有条河,上面有座桥,里面有群鸭

  • 我家门前有条河,(河 this)上面有座桥,(河 this)里面有群鸭

  • 面试题 =》this 是在执行时动态读取上下文决定,而非创建时

考察重点 - 各个使用态中的指针指向

函数中的直接调用 - this 指向执行全局

function test() {
  console.log("函数内部的this", this);
}
test();

显式绑定

// 改变this指向 call | apply | bind
  • 面试题 1 call | apply | bind 区别 1.传参不同,call 依次传参,apply 数组传参 2.bind 直接返回方式不同,需再次调用

    • 面试题 2 bind 的原理 | 手写 bind
    • 原理或手写类题目解题思路
      1. 说明原理,写下注释
      1. 根据注释,补全代码
    // 1.需求:手写bind=>bind位置=》Function.prototype
    Function.prototype.newBind = function () {
      // 2.bind是什么?
      const _this = this;
      const args = Array.prototype.silce.call(arguments);
      // 输入:args的特点--第一项是新的this,其余项函数传参
      const newThis = args.shift();
      // 输出:返回一个函数 =》 构造一个函数 =》 返回原函数的结果并继承传参
      return function () {
        return _this.newApply(newThis, args);
      };
    };
    
    Function.prototype.newApply = function (context) {
      // 边缘检测
      if (typeof this !== "function") {
        throw new TypeError("使用正确的函数进行调用");
      }
      // 兜底
      contxt = context || window;
      // 执行函数的替换
      context.fn = this;
      // 临时挂载执行fn => 销毁临时挂载
      let result = arguments[1] ? context.fn(...arguments[1]) : context.fn();
      delete context.fn;
      // 返回结果
      return result;
    };
    

    作用域和上下文 =》 束缚 =》 如何突破作用域束缚

    闭包

    function sayHello() {
      let name = "tom";
      return function () {
        console.log(name);
      };
    }
    const myName = sayHello();
    // 局部变量name在外部可以拿到
    

    =》js module =》闭包 | 局部变量 | 模块内变量的返回