优雅的理解 call 和 apply 的使用方法

  • 作者在看到一篇优雅的使用 js 的各种方法解决算法的时候产生的疑问,到底什么时候使用 apply 和 call 啦?

  • 每次看到别人用 apply 和 call 其实从以前的懵懵懂懂到现在的明白,但是自己从来未下手去用过,最近比较闲。开始打一下 JavaScript 的算法基础,刷一下简单的算法题目。然后从自己拙劣的解题思路和方法比较大牛的优雅的JavaScript的方法后有所感想。

先来看一个?栗子

Q:将数组 arr 中的元素作为调用函数 fn 的参数

这里面涉及几个知识点,函数调用的方法,apply 和 call 的使用。

  • 创建函数
function argsAsArray(fn, arr) {
    // code here
}
复制代码
  • 输入
argsAsArray(
    function (greeting, name, punctuation) {
        return greeting + ', ' + name + (punctuation || '!');
    }, ['Hello', 'Ellie', '!']
)
复制代码
  • 输出

Hello, Ellie!
复制代码

看完上面的题目,大家知道怎么解题吗?(答案在本文最后)如果你想到了 apply 和 call,那么恭喜你,基础扎实,然后就是对 call 和 apply 的基本了解和掌握了。看下面?

怎么理解 apply 和 call

  • 第一步:看看 MDN 的解释
    • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
  • 第二步:跟着我看一个 demo
function cat(){};

cat.prototype = {
    obj:"fish",
    say:function(){
        return "I love" + this.obj;
    }
}

function doggie(){};

doggie.prototype = {
    obj:"bone",
    eat:function(){
        return "I love" + this.obj;
    }
}

function ATM(){};

ATM.prototype = {
    obj:"monster",
    fight:function(){
        return "I love" + this.obj;
    }
}

复制代码
  • 上面的理解?:猫吃鱼,狗吃肉(骨头),奥特曼爱打小怪兽。

突然有一天:

  • 有天狗想吃鱼了

cat.say.call(doggie,cat.obj)
//猫.吃鱼.call(狗,鱼)

//狗就吃到鱼了

复制代码
  • 猫成精了,想打怪兽
ATM.fight.call(cat,ATM.obj)

//奥特曼.打小怪兽.call(猫,小怪兽)

复制代码

就这样记住了。

来训练一下实战怎么优雅(强行)的用上 apply 和 call

  • Q:删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组
  • 输入 : [1,2,3,4]
  • 输出 : [1,2,3]

很简单对不对,不删除原来的数组,我们 clone 一个数组。然后使用 JavaScript 自带的数组方法 pop() 就行了。

  • 解法一

function truncate(arr) {
    var newArr = arr.slice(0);
    // slice(0) 复制数组
    newArr.pop();
    return newArr;
}

复制代码

当然你可以优雅的使用 slice 来搞定

  • 解法二

function truncate(arr) {
    return arr.slice(0,-1);
}

复制代码

现在问题来了,我们要用 apply 来搞定问题咋办啦?(实现一个数组 copy)

还是创建一个新的数组,我们明白了凹凸曼和小猫小狗的用法以后,我们将 newArr 借用 [] 数组的 push 方法,对象是 arr,而达到 copy 一个数组的功能。


function truncate(arr) {
    var newArr=[];
    [].push.apply(newArr, arr);
    newArr.pop();
    return newArr;
}
复制代码

当然有很多可供实现的 apply 的使用情况,可能我这个不是很确切,大家可以鞭策一下,共同学习和理解

A(最开始题目的答案)

function argsAsArray(fn, arr) {
    return fn.apply(this,arr);
}
复制代码

这里解释两个点

  • 一,调用函数有几种方法?
    • 直接调用: obj.func()
    • call: func.call(obj,arg) // 列出参数
    • apply: func.apply(obj,[a,b,c,...]) // 列出数组
  • 二,call 和 apply 的区别
    • 般情况下都是对象调用函数,但此处是函数调用数组对象,用call(), apply()。第一个参数是传给当前函数对象。但是call()需要将参数挨个列出,apply直接传入数组对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值