看了非常多的网络教程,基本上知道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 狼叔
必备技能,怎么能说鸡肋呢?嗷呜。。。
@i5ting 现在比较困扰的是这三个函数的使用场景,在什么样的情况下使用这三个函数
@TimLiu1 看各种知名库的源码,比如co
@TimLiu1 写框架或通用类会经常用到
如果只看ES6+确实挺鸡肋
恰恰相反,call和apply是神器
这才是神器,我举个简单的例子,不用扩展运算符…你怎么把一个数组展开?
@TimLiu1 不,就用es5
我以前用这个就是为了实现继承,现在有extends,这东西基本就不用了
@zy445566 soga
@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方法执行
函数式编程必备
存在即是合理
@fantasticsoul 灰常感谢 From Noder
当你的代码都是自己写自己用的时候,的确 用处不大
当你的代码是写给别人用的时候,比如框架,类库,这两个在处理外部函数时还是很常用的
你要是自己写个web项目,那可能是用不上.但是如果写包时候多半就需要了
call可以改变this、this在特定情况下会指向prototype、那么换句话说,我们就可以用call实现原型转换。。
call, apply, bind都是开发中常用的
@qinyang912 因为我们公司是全node,所有项目中几乎没看到有人用call,也有很牛的架构师,自己看教程有比较晦涩,很难想到运用场景,你们开发常用在哪个方面?
@baka397 看来理解的不错
@zxc122333 赞👍
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))
})
}