面试-js 中的 this

发布于:2023-03-18 ⋅ 阅读:(679) ⋅ 点赞:(0)

1. this 指向

  • 普通函数中的 this 指向调用它的那个对象。这个和作用域是相反的。

    // 声明位置
    var me = {
    name: 'xiuyan',
    hello: function() {
      console.log(`你好,我是${this.name}`)
    }
    }
    
    var you = {
    name: 'xiaoming',
    hello: function() {
      var targetFunc = me.hello
      targetFunc()
    }
    }
    
    var name = 'BigBear'
    
    // 调用位置
    you.hello()
    
    -结果:'BigBear'
    -原因:因为调用 hello 的时候它所在的对象是 you,所以它内部的 this 会指向 you,但是在它内部调用 targetFunc 的时候没有加 this,所以这个函数相当于 window 调用的,所以是 'BigBear'
  • 特殊情况下的 this 指向,以下几种都会指向 window

    • 立即执行函数
    • setTimeout 中传入的函数
    • setInterval 中传入的函数
  • 如果改变 this 的指向

    • 箭头函数:this 指向书写它的位置
    var name = 'BigBear'
    var me = {
    name: 'xiuyan',
    // 声明位置
    hello: () => {
       console.log(this.name)
    }
    }
    
    // 调用位置
    me.hello() // BigBear
    • 构造函数,指向新构建的对象
    • bind、call、apply 重新定义 this 的指向。其中 bind 不会运行函数,只改变 this,其他两个都会执行函数,并返回结果。apply 的第二个参数是数组,其他两个都和原函数的参数一样。

    2. 实现 bind、call、apply

  • 特点:所有函数都可以继承;改变了 this
  • 实现 call:相当于在当前的 obj 上加了一方法,这个方法的实现是要改变内部 this 的函数,执行完从这个 obj 上删除该方法就可

    Function.prototype.myCall = function(context, ...args) {
    if (context === null || context === undefined) {
    context = typeof window === 'undefined' ? global : window
    }
    let key = Symbol('fn');
    context[key] = this; // this 是我们要运行的函数
    const res = context[key](args);
    delete context.func;
    return res;
    }
    
  • 实现 bind:bind 生成一个函数,函数的调用分为 new 和 直接调用两种。

    Function.prototype.myBind = function (context, ...args) {
    if (typeof this !== 'function') {
      thow new TypeError('not a funtion')
    }
    let self = this;
    function resultFn (...args2) {
      if (this indtanceof resultFn) {
    // 如果是 new 的形式绑定函数
      return new self(...args, ...args2)
    }
    return self.call(context, ...args, ...args2)
    }
    resultFn.prototype = Object.create(self.prototype)
    return resultFn
    }

    3. 执行上下文

  • 全局上下文:全局代码所处的环境,不在函数中的代码都在全局执行上下文中

    • 创建时机:在进入脚本时,只创建一次
    • 创建阶段:

      • 创建全局对象、this,并将 this 指向全局对象
      • 给变量和函数安排内存空间
      • 给变量赋值 undefined,将函数声明放入内存
      • 创建作用域链
    • 执行阶段:执行代码
  • 函数上下文:在函数调用时创建的上下文

    • 创建时机:函数调用时
    • 创建阶段:

      • 创建参数对象、this,将 this 指向调用它的对象
      • 其他同全局上下文
    • 代码执行完毕,函数上下文的生命周期久结束了,既出栈。
  • eval 执行上下文:开发中不要使用
本文含有隐藏内容,请 开通VIP 后查看