【build your own xxx】实现你自己的call和apply

简介: 【build your own xxx】实现你自己的call和apply

call


首先看看call是干什么的,从MDN上扒一张图:

image.png

举个例子

 function showName(gender, age){
      console.log(this.name, " ", gender, " ", age)
    }
    var obj = {
        name: "亚古"
    }
    showName.call(obj, "female", 22)// 亚古   female   22

梳理思路


可以看出来Func.call(obj, arg1, arg2...)实现了这么几件事:

  1. 以obj.Func的方式调用
  2. 把参数arg1, arg2 ...传递给Func
  3. 不对obj和Func造成副作用


实现


Function.prototype.Zcall = function (othis) {
        othis.fn = this;
        othis.fn();
  }
    showName.Zcall(obj) // 亚古   undefined   undefined
复制代码

第一个步骤已经实现了,但是很明显的是这样子会对传入的othis造成副作用,即给othis对象无缘无故添加了一个方法,所以:

Function.prototype.Zcall = function (othis) {
        othis.fn = this;
        othis.fn();
        delete othis.fn;
    }


副作用已经消除了,接下来就是参数的问题,这里有个问题是参数个数是不定的,貌似可以使用一个数组来arr保存住arguments里面的参数,然后再执行othis.fn(arr)。但是,这样等于说只给fn传了一个数组参数,并不能达到目的。

此时问题转化为我们如何实现像 othis.fn(arguments[0], arguments1, arguments2 ...) 这样的语句呢? 此时可以想起一个不怎么常用的方法eval

image.png

简单的说就是可以把字符串解析为JavaScript语句来执行。 借助eval,改写Zcall方法:

Function.prototype.Zcall = function (othis) {
    othis.fn = this;
    let args = [];
    for(let i = 1, len = arguments.length;i < len;i++) {
      args.push("arguments[" + i + "]");
    }
    // othis.fn();
    eval("othis.fn(" + args + ")");
    delete othis.fn;
  }
复制代码

其实就是用args把arguments用字符串的方式保存住,然后在eval方法中再把字符串重新解析为语句。


apply


同理来实现apply:

Function.prototype.Zapply = function (othis) {
    othis.fn = this;
    let argsArr = arguments[1];
    if (!arguments[1]) {
      let args = [];
      for(let i = 0, len = arguments[1].length;i < len;i++) {
        args.push("arguments[1][" + i + "]");
      }
      eval("othis.fn(" + args + ")");
    }else{
      othis.fn();
    }
    delete othis.fn;
  }

参考资料:

MDN-eval

MDN-apply

JavaScript深入之call和apply的模拟实现

相关文章
|
30天前
|
Linux iOS开发 MacOS
pnpm全局安装报错:Run “pnpm setup“ to create it automatically, or set the global-bin-dir setting, or the PN
pnpm全局安装报错:Run “pnpm setup“ to create it automatically, or set the global-bin-dir setting, or the PN
773 0
|
12月前
CMake Error: The source “xxx“ does not match the source “yyy“ used to generate cache. Re-run cmake
CMake Error: The source “xxx“ does not match the source “yyy“ used to generate cache. Re-run cmake
524 0
|
9月前
|
数据库管理
SVN 执行cleanup报错:Cleanup failed to process the following paths : 解决方法
引用:https://www.cnblogs.com/pinpin/p/11395438.html 在SVN更新时提示文件被锁住了,要求执行 clean up操作,执行clean up时又报clean up failed。造成的原因是在某次更新后,点击了cancel按钮,操作没有完成所以会锁住。解决方法如下:
380 0
|
2天前
|
JavaScript 前端开发
|
30天前
|
缓存
pytest 运行测试函数报错的解决办法 TypeError: calling <function xxx> returned None, not a test
pytest 运行测试函数报错的解决办法 TypeError: calling <function xxx> returned None, not a test
159 0
|
前端开发
|
开发工具 git
编译pluma:configure.ac:229: error: required file ‘pluma/mate-submodules/Makefile.in‘ not found
编译pluma:configure.ac:229: error: required file ‘pluma/mate-submodules/Makefile.in‘ not found
106 0
对‘avformat_find_stream_info’未定义的引用、to the PKG_CONFIG_PATH environment variable
对‘avformat_find_stream_info’未定义的引用、to the PKG_CONFIG_PATH environment variable
68 0
|
缓存
【已解决】npm start 报错 Could not freeze ...: cannot read properties of undefined (reading ‘hash‘)
npm start 报错 Could not freeze ...: cannot read properties of undefined (reading ‘hash‘)
441 0

热门文章

最新文章