首页 > 其他分享 >js中的apply方法并模拟实现自己的apply方法

js中的apply方法并模拟实现自己的apply方法

时间:2022-09-28 01:33:46浏览次数:70  
标签:console log js thisArg apply array 方法

apply方法

定义

call()方法,在mdn中的定义:
apply() 方法调用一个具有给定this值的函数,以及以一个数组(或类数组对象)的形式提供的参数。(它的作用和使用和call方法一致,唯一的区别就是call方法传递的是一个个参数的列表,apply方法传递的是参数的数组集合。Call方法详细请看 call方法解析。

语法

func.apply(thisArg, [argsArray])
apply方法传递两个参数,第一个参数传递的是所要改变指向的值(当该函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。),第二个参数是所要传递的参数(参数是一个数组集合)。

返回值

返回调用函数的返回值。若该函数没有返回值,则返回 undefined。

使用

    let myName = {
        nameStr: 'dahua'
    }

    function sayName(res, res2) {
        console.log(this);
        console.log(this.nameStr);
        console.log(res);
        console.log(res2);
    }
    sayName.apply(myName, [1,3,'a']);

    // {nameStr: "dahua"}
    // dahua
    // 1
    // 3

上述代码改变this指向指向myName对象,并传入了一个数组参数,在sayName函数执行的时候会把传入的数组展开进行参数传递。还可以像下方这样子使用:

    let array = ['a', 'b'];
    let elements = [0, 1, 2];
    array.push.apply(array, elements);
    console.info(array); // ["a", "b", 0, 1, 2]

上述代码是调用了数组的push方法。并通过apply方法直接传入了数组参数,实现数组的合并。

模拟实现自己的apply方法

第一个参数具体指向的值,在call方法中已经详细验证不在赘述,可以直接查看call方法解析( 病历证明),直接实现自己的apply方法和验证。

思路:

核心就是根据this的指向规则。(this详细指向规则可参考this解析)

步骤:

1、 因为是所有函数的方法,所以直接在原型上创建一个方法
2、 先判断传入的第一个参数thisArg的类型,进行分别处理
3、给thisArg添加一个属性,并把this赋值给它
4、调用该方法,并将参数传入进去并展开
5、删除改thisArg创建的属性
6、返回函数调用的返回值
代码如下:

    // 挂在Function的原型上
    Function.prototype.myApply = function(thisArg, res) {
        // 判断第一个参数thisArg是否是undefined或者null,是的话就赋值给window
        if (typeof thisArg === 'undefined' || thisArg === null) {
            thisArg = window;
        }
        // 对传入的值thisArg就行包装
        thisArg = Object(thisArg);
        // 给传入的值thisArg创建属性,为防止thisArg已经有对应的对应进行覆盖,所以使用Symbol创建唯一值
        const keyFn = Symbol('__myKeyFn__');
        // 此时的this指向调用myCall方法的函数,将它指向thisArg[keyFn]。
        // 这里也就是利用了this的指向规则
        thisArg[keyFn] = this;
        // 调用该方法传入参数,并展开
        const reasult = thisArg[keyFn](...res);
        // 删除thisArg创建的属性
        delete thisArg[keyFn];
        // 返回函数的返回值
        return reasult;
    }
测试

上面模拟实现了自己的apply方法,下面就测试一下功能是否正常:

let myName = {
        nameStr: 'dahua'
    }

    function sayName(res, res2) {
        console.log(this);
        console.log(this.nameStr);
        console.log(res);
        console.log(res2);
    }
    sayName.myApply(myName, [1,3,'a']);

    // {nameStr: "dahua", Symbol(__myKeyFn__): ƒ}
    // dahua
    // 1
    // 3

    let array = ['a', 'b'];
    let elements = [0, 1, 2];
    array.push.myApply(array, elements);
    console.info(array); // ["a", "b", 0, 1, 2]

测试结果和自带apply方法一致。

使用call方法实现apply方法

当我们实现了call方法的时候可以直接使用实现的call方法实现apply方法。如:

    Function.prototype.myApply = function (thisArg, res) {
        return this.myCall(thisArg, ...res);
    }
测试
let myName = {
        nameStr: 'dahua'
    }

    function sayName(res, res2) {
        console.log(this);
        console.log(this.nameStr);
        console.log(res);
        console.log(res2);
    }
    sayName.myApply(myName, [1,3,'a']);

    // {nameStr: "dahua", Symbol(__myKeyFn__): ƒ}
    // dahua
    // 1
    // 3

    let array = ['a', 'b'];
    let elements = [0, 1, 2];
    array.push.myApply(array, elements);
    console.info(array); // ["a", "b", 0, 1, 2]

测试结果与自己实现的apply方法一致。

来源:http://www.12tebing.com/news/780.html

标签:console,log,js,thisArg,apply,array,方法
From: https://www.cnblogs.com/bkycnd/p/16736587.html

相关文章

  • js中的bind方法并模拟实现自己的bind方法
    Js中bind方法使用和实现前面我们已经模拟实现了call和apply方法,今天来实现下同样可以改变this指向但是又有点不同得方法-->bind方法。定义首先来看下bind方法在mdn中......
  • python安装weditor报错error subprocess-exited-with-error的解决方法
    使用pip安装weditor失败,报错内容:  解决方法:第一步输入gitclonehttps://github.com/openatx/weditor第二步输入 pip3install-eweditor     验......
  • 前端三件套 HTML+CSS+JS基础知识内容笔记
    HTML基础目录HTML基础HTML5标签doctype标签html标签head标签meta标签title标签body标签文本和超链接标签标题标签段落标签换行标签水平标签强调标签图片标签与超链接标签......
  • TE对象message js脚本简单写法
        TE里的对象和图层都支持添加message,其中message类型中有一类为Script,在弹出的框里可以写JavaScript脚本,下图就是切换到脚本信息下: 写一个了简单的脚本示例:<scrip......
  • JS 刷新页面所有方法
    window.location.reload();使用window.open()弹出的弹出窗口,刷新父窗口非模态刷新父页面:window.opener.location.reload()使用window.showDialog弹出的模式窗口模态刷新父......
  • VueJs 自定义过滤器使用总结
    在这个教程中,我们将会通过几个例子,了解和学习VueJs的过滤器。我们参考了一些比较完善的过滤器,比如orderBy和filterBy。而且我们可以链式调用过滤器,一个接一个过滤。因此,我......
  • vuejs 开发问题解决方案总结一
    文章中提到的很多东西都在我的demo中用到,我的demo地址:​​https://github.com/MrZhang123/Vue_project/tree/master/vue_spa_demo​​1.Vuejs组件vuejs构建组件使用Vue.comp......
  • js循环数组各种方法array 汇总-基础
    js循环数组各种方法array汇总-基础这几天做系统,又用到多维数组循环交叉。所以总结一套以供参考记录1.varmyStringArray=["Hello","World"];2.......
  • 信号处理(1) --常用信号平滑去噪的方法
    前言:最近研究汽车碰撞的加速度信号,在信号的采集过程中难免遇到噪音,导致信号偏差,为了更好的反映系统情况,故常需要信号去噪,本文分享一些常用信号平滑去噪的方法。关键字:信号;去......
  • django项目 数据migrate迁移成功 数据库未生成表 表现:Running migrations: No mig
    现象:python pythonmanage.pymigrate后提示:Runningmigrations:  Nomigrationstoapply.解决方法: 找到相应数据库的数据库表django_migrations,之后有一个app字......