面试题---this指向,手写call,apply,bind

101 阅读2分钟

如何确认this的值

image.png

      /**
       * 如何确认this的值
       * 1.全局执行环境
       *   严格模式,非严格模式:this指向全局对象----(window)
       * 2.函数内部
       *  2.1 直接调用
       *   严格模式下:undefined
       *   非严格模式:全局对象(window)
       *  2.2 对象方法调用
       *   严格模式,非严格模式:调用者
       * 3.开启严格模式
       *   脚本开启: 'use strict'
       *   函数内部开启:'use strict'
       *   注意:'use strict'写在代码顶端
       * */

image.png

image.png

image.png

如何指定this的值

image.png

image.png

image.png

image.png

image.png

手写call方法

每天搞透一道JS手写题💪「Day4手写函数的三种原型方法(call、apply、bind)」 - 掘金 (juejin.cn) image.png 【手写系列】call,apply与bind以及详细解析

手写call方法02-Symbol调优

image.png

    // 思路
    // 1、将方法挂载到我们传入的thisArg
   // 2、将挂载以后得方法调用
   // 3、将我们添加的这个属性删除

      /**
       * 手写call方法
       *  1. 定义myCall方法
       *  2. 设置this并调用原函数
       *  3. 接收剩余参数并返回结果
       *  4. 使用Symbol调优
       * */
      // 1. 定义myCall方法
      // 3. 接收剩余参数并返回结果
      Function.prototype.myCall = function (thisArg, ...args) {
        // 2. 设置this并调用原函数
        // 给thisArg加一个一定和原属性不重名的新属性(方法)
        // 4. 使用Symbol调优
        thisArg = thisArg === null || undefined ? globalThis : Object(thisArg);
        const key = Symbol("key");
        // thisArg.key
        thisArg[key] = this;
        const res = thisArg[key](...args);
        delete thisArg[key];
        return res;
      };

      // ------------- 测试代码 -------------
      const food = {
        name: "西兰花炒蛋",
      };
      function func2(numA, numB, numC) {
        console.log(this);
        console.log(numA, numB, numC);
        return numA + numB + numC;
      }
      const res2 = func2.myCall(null, 2, 4, 6);
      console.log("res2:", res2);

      // ------------- 测试Symbol -------------
      // 调用Symbol内置函数,可以传入字符串作为标记
      // 返回一个唯一的值
      // const s1 = Symbol()
      // const s2 = Symbol()
      // console.log(s1 === s2)-----false
      // const s3 = Symbol('itheima')
      // const s4 = Symbol('itheima')
      // console.log(s3 === s4)


手写apply方法

image.png


    /**
     * 手写apply方法
     *  1. 定义myApply方法
     *  2. 设置this并调用原函数
     *  3. 接收参数并返回结果
     * */
    // 1. 定义myApply方法
    // 3. 接收参数并返回结果
    Function.prototype.myApply = function (thisArg, args) {
      // console.log('myApply执行啦')
      // 2. 设置this并调用原函数
      const key = Symbol('key')
      thisArg[key] = this
      const res = thisArg[key](...args)
      delete thisArg[key]

      return res
    }



    // ------------- 测试代码 -------------
    const person = {
      name: 'itheima'
    }

    function func(numA, numB) {
      console.log(this)
      console.log(numA, numB)
      return numA + numB
    }

    const res = func.myApply(person, [2, 8])
    console.log('返回值为:', res)





手写bind方法

image.png


    /**
     * 手写bind方法
     *  1. 定义myBind方法
     *  2. 返回绑定this的新函数
     *  3. 合并绑定和新传入的参数
     * */
    //  1. 定义myBind方法
    Function.prototype.myBind = function (thisArg, ...args) {
      // console.log('myBind调用了')
      // 2. 返回绑定this的新函数
      return (...reArgs) => {
        // this:原函数(原函数.myBind)
        return this.call(thisArg, ...args, ...reArgs)
      }
    }


    // ------------- 测试代码 -------------
    const person = {
      name: 'itheima'
    }

    function func(numA, numB, numC, numD) {
      console.log(this)
      console.log(numA, numB, numC, numD)
      return numA + numB + numC + numD
    }

    const bindFunc = func.myBind(person, 1, 2)

    const res = bindFunc(3, 4)
    console.log('返回值:', res)