觉得call和apply函数在我们编程中是鸡肋,大家怎么看
发布于 7 年前 作者 TimLiu1 5501 次浏览 来自 问答

看了非常多的网络教程,基本上知道call的主要作用就是改变this指向 ,更好的理解就是改变了我们需要执行函数的上下文,把上下文变成我们指定的函数或则对象。

function name() {
    return {
        name:"timliu",
        sayName : function () {
        console.log("My name is " + this.name);
    }
}
}
name().sayName();	//My name is timliu

change = {
    name: "狼叔"
}
name().sayName.call(change);		//My name is 狼叔
name().sayName.apply(change);       //My name is 狼叔
32 回复

必备技能,怎么能说鸡肋呢?嗷呜。。。

@i5ting 现在比较困扰的是这三个函数的使用场景,在什么样的情况下使用这三个函数

@TimLiu1 看各种知名库的源码,比如co

@TimLiu1 写框架或通用类会经常用到

如果只看ES6+确实挺鸡肋

恰恰相反,call和apply是神器

这才是神器,我举个简单的例子,不用扩展运算符…你怎么把一个数组展开?

@artisan ES6的解构 From Noder

@nullcc 可以说说你的理解吗,比如你用到的场景 From Noder

@zy445566 怎么理解,比如 From Noder

我以前用这个就是为了实现继承,现在有extends,这东西基本就不用了

@TimLiu1 很多用处,给你举个最简答的常用例子,追求极致性能的时候会用上,比如很多工具类会这样写: a.js文件 var slice = Array.prototype.slice;

export.doSomething = function(inputArr){ var otherArr = slice.call(inputArr); }

export.doSomething2 = function(inputArr){ var otherArr = inputArr.slice(); }

b.js文件 var a = require(’./a’); var arr = [1,2,3,4,5,6];

//tag1 for(var i =0; i <1000000; i++){ a.doSomething(arr); }

//tag2 for(var i =0; i <1000000; i++){ a.doSomething2(arr); }

//tag1 处得代码是要比tag2的循环要快的,因为tag1里的slice是直接调用,而tag里的slice总是先查一次arr对象自己身上有没有slice方法,没有的话再去自己的__proto__上即Array.prototype上找slice方法执行

函数式编程必备

存在即是合理

@Telanx …不同意 From Noder

@fantasticsoul 灰常感谢 From Noder

当你的代码都是自己写自己用的时候,的确 用处不大

当你的代码是写给别人用的时候,比如框架,类库,这两个在处理外部函数时还是很常用的

你要是自己写个web项目,那可能是用不上.但是如果写包时候多半就需要了

call可以改变this、this在特定情况下会指向prototype、那么换句话说,我们就可以用call实现原型转换。。

call, apply, bind都是开发中常用的

@qinyang912 因为我们公司是全node,所有项目中几乎没看到有人用call,也有很牛的架构师,自己看教程有比较晦涩,很难想到运用场景,你们开发常用在哪个方面?

@baka397 看来理解的不错

call-动态this apply-动态this, 动态参数个数

@TimLiu1 bind一般是把函数当参数传递时使用,保证回调执行的时候上下文是指定的, 最开始我们用call和apply来做的,但是每次都需要传递一个上下文; call和apply更多是在一些公共库里面使用;还有一个apply比较常用的地方,Array.prototype.push.apply来实现concat功能

举个栗子:Math.max.apply(Math, [1,2,3,4,5]),很方便有木有

这两个方法是做apm必备的条件。

@AserSayHi 这样写有什么好处啊?Math.max(1,2,3,4,5);不是更方便么?

@muyoucun557 只是举个例子,重点是说明apply跟call方法并不鸡肋。我所说的方便在于:假设我的例子中的数组非直接量,而是一个参数呢?

今天刚写了封装任意Callback(err, ...res)使之返回Promise

function runPromise (fun, that, ...rest){
    return new Promise(function(resolve, reject){
        function callback(err, ...rest){
            if (err) {
                reject(err);
            } else {
                if (rest.length == 0){
                    resolve();
                } else if (rest.length == 1){
                    resolve(rest[0])
                } else {
                    resolve(rest)
                }
                
            }
        }
        fun.apply(that, rest.concat(callback))
    })
}
回到顶部