JavaScript-实现函数方法-改变this指向call apply bind

this

  • 函数执行时决定的不是定义时决定的
  • this只和函数的调用有关*
  • obj.fn() fnthis就是obj arr[0] () this就是arr

重定义

call

  • 会直接执行函数
  • 函数的参数逐个传进去
实现
  • 首先先判断thisArg参数 如果为空就默认window 这里运用了||运算符 有一个t结果就为t 所以短路效果为前面的表达式结果为t 后面的表达式就不执行

补充说明&&运算符 前面一个f结果就为f 所以短路效果是前面为f后面不执行

  • symbol(基本数据类型)有唯一性 可以保证属性与原对象不冲突 let key = Symbol('temp')创建一个symbol类型的变量key其中temp是这个变量的描述符
  • 利用对象的方法中的this指向对象 :通过把这个函数给thisArg对象的方法再通过这个对象调用就改变了函数this的指向 其中利用数组的展开运算符 把value(剩余参数数组)挨个传进这个方法完成了mycall改变this指向和直接执行函数的功能
js 复制代码
    //实现call
    Function.prototype.myCall = function (thisArg, ...value) {
      //如果参数为空 就默认是window
      //利用||特性
      thisArg = thisArg || window

      let key = Symbol('temp')
      thisArg[key] = this
      //利用...数组的展开运算符把value的所有元素 逐个全部传入
      thisArg[key](...value)
      delete thisArg[key]

    }
  • 测试用例
js 复制代码
//测试用例
    //this指向对象
    function fnCall(a, b) {
      console.log(this, a, b);
    }
    fnCall.myCall(obj, 1, 2)
    //this指向函数
    function fn1() {
      console.log('这是测试函数');
    }
    fnCall.myCall(fn1, 1, 2)

apply

  • 也会直接执行函数
  • 参数以对象(一般是数组的形式传进去)
实现

mycall的基本思想是一样的区别如下

  • 因为参数是数组形式 所以myApply中的value参数不需要用剩余参数数组...value直接获取传入的数组value即可 然后还是使用...展开运算符把参数数组展开传入
js 复制代码
 //实现apply
     Function.prototype.myApply = function (thisArg, value) {
      thisArg = thisArg || window
      let key = Symbol('temp')
      thisArg[key] = this
      //利用...数组的展开运算符把value的所有元素 逐个全部传入
      thisArg[key](...value)
      delete thisArg[key]
    }
    fnCall.myApply(obj, [1, 2])
  • 测试用例同mycall

bind

  • 参数逐个传入
  • 返回新数组 调用之后才执行(参数自动传进去 this改变)
实现

不会立即执行函数 而是返回新的函数

  • 因为返回的新函数中的this就不是调用函数了 所以要把this放进fn函数里
  • 返回一个新函数 先给thisArg对象添加fn方法(就是要改变this的函数) 然后把原函数的返回结果 也就是对象方法的结果原函数的返回结果放进result作为新函数的返回结果 删除属性避免对原thisArg造成干扰 最后把result变量return出去

举例子(没有this干扰)理解result变量的必要性 这里把内部函数的返回值return出去 就能实现调用outside函数返回一个inside函数并且把他的她的返回值也复制了最终代码

js 复制代码
 //实现bind
    //创建新函数 this绑定到指定对象上
    Function.prototype.myBind = function (thisArg, ...value) {
      //不会立即执行函数 而是返回新的函数
      thisArg = thisArg || window
      let fn = this //把调用的函数存起来
      return function () {
        let key = Symbol('temp') //每次调用都创建新的临时键
        thisArg[key] = fn
        const result = thisArg[key](...value)
        delete thisArg.fn
        return result  //返回原函数的执行结果
      }
    }
  • 测试用例
js 复制代码
//生成新的函数
    function bindFn(a, b) {
      console.log('myBind结果', this, a, b);
    }
    let Person = {
      name: 'a'
    }
    const newBindfn = bindFn.myBind(Person, 2, 1)
//传入thisArg为空的情况
    const newBindfn1 = bindFn.myBind('', 2, 3)  //this指向window
//新生成的函数返回值
    function fn() {
      return '函数返回结果'
    }
    console.log(fn.myBind(Person)());//函数返回结果
相关推荐
一人の梅雨6 分钟前
中国制造网商品详情接口进阶实战:跨境场景下的差异化适配与问题攻坚
java·前端·javascript
muddjsv24 分钟前
JavaScript 结合 Flex 布局的深度解析 (解锁前端布局新范式)
前端·javascript
小宇的天下28 分钟前
Calibre :Standard Verification Rule Format(SVRF) Manual (1-2)
前端·javascript·windows
冲刺逆向29 分钟前
【js逆向案例五】瑞数通杀模版
前端·javascript·typescript
利刃大大31 分钟前
【Vue】Vue介绍 && 声明式渲染 && 数据响应式
前端·javascript·vue.js·前端框架
2501_9445264236 分钟前
Flutter for OpenHarmony 万能游戏库App实战 - 多语言国际化实现
android·java·开发语言·javascript·flutter·游戏
2501_944521591 小时前
Flutter for OpenHarmony 微动漫App实战:骨架屏加载实现
android·开发语言·javascript·数据库·redis·flutter·缓存
光影少年1 小时前
前端如何实现一个高精准定时器和延时器
前端·javascript·react.js·web·ai编程
摘星编程1 小时前
React Native + OpenHarmony:Jotai原子派生状态
javascript·react native·react.js
冰暮流星1 小时前
javascript之do-while循环
开发语言·javascript·ecmascript