Daily-Interview-Question icon indicating copy to clipboard operation
Daily-Interview-Question copied to clipboard

第 48 题:call 和 apply 的区别是什么,哪个性能更好一些

Open zeroone001 opened this issue 6 years ago • 14 comments

  1. Function.prototype.apply和Function.prototype.call 的作用是一样的,区别在于传入参数的不同;
  2. 第一个参数都是,指定函数体内this的指向;
  3. 第二个参数开始不同,apply是传入带下标的集合,数组或者类数组,apply把它传给函数作为参数,call从第二个开始传入的参数是不固定的,都会传给函数作为参数。
  4. call比apply的性能要好,平常可以多用call, call传入参数的格式正是内部所需要的格式,参考call和apply的性能对比

zeroone001 avatar Apr 04 '19 00:04 zeroone001

尤其是es6 引入了 Spread operator (延展操作符) 后,即使参数是数组,可以使用 call

let params = [1,2,3,4]
xx.call(obj, ...params)

kangkai124 avatar Apr 04 '19 02:04 kangkai124

两者区别在参数传递格式: apply( ):两个参数,第一个是运行函数的作用域,第二个是参数数组(可以是array的实例,或者arguments对象)。 call( ):参数个数不定,第一个是运行函数的作用域,其余传递给函数的参数逐个列出。 apply()和 call()的2个作用:给函数传参、扩充作用域; 至于是使用 apply( )还是 call( ),完全取决于你采取哪种给函数传递参数的方式最方便。

anyxl avatar Apr 15 '19 06:04 anyxl

call 比 apply 的性能好, 我的理解是内部少了一次将 apply 第二个参数解构的操作

chenzesam avatar Jul 09 '19 12:07 chenzesam

apply 需要对 argArray 做很多判断

francecil avatar Oct 21 '19 03:10 francecil

尤其是es6 引入了 Spread operator (延展操作符) 后,即使参数是数组,可以使用 call

let params = [1,2,3,4]
xx.call(obj, ...params)

然而这玩意要是被babel或者ts过了一遍变成es5全都变成了 xxx.call.apply(obj,params) image image

liaoyinglong avatar Nov 19 '19 14:11 liaoyinglong

.call方法会立即执行!

.bind方法会返回函数的拷贝值,但带有绑定的上下文! 它不会立即执行。

3460741663 avatar Mar 01 '20 14:03 3460741663

大家好像不喜欢看ECMA草案。

call: image

apply: image

可以看到算法步骤中,apply多了CreateListFromArrayLike的调用,其他的操作几乎是一样的(甚至apply仍然多了点操作)。从草案的算法描述来看,call性能 > apply性能。

random-yang avatar Mar 16 '20 02:03 random-yang

  1. Function.prototype.apply和Function.prototype.call 的作用是一样的,区别在于传入参数的不同;
  2. 第一个参数都是,指定函数体内this的指向;
  3. 第二个参数开始不同,apply是传入带下标的集合,数组或者类数组,apply把它传给函数作为参数,call从第二个开始传入的参数是不固定的,都会传给函数作为参数。
  4. call比apply的性能要好,平常可以多用call, call传入参数的格式正是内部所需要的格式,参考call和apply的性能对比

call的性能是比apply好,但是我测试了一下,如果使用call的时候,用上解构赋值把参数传入,性能比起直接把整个数组做为参数传入apply差,所以还是要看参数怎么传入吧

QZEming avatar Mar 21 '20 15:03 QZEming

  1. call ( ) 语法 : 函数名 .call (修改后的this指向 , arg1 ,arg2(实参))
    • 适合函数原本 只有一个形参
  2. apply ( ) 语法 : 函数名 . apply (修改后的this指向 , 数组或伪数组)
    • 适合函数有多个参数

zhenhong820 avatar Apr 14 '20 09:04 zhenhong820

Call 和 apply 的区别是什么,哪个性能更好一些 Call 和 apply 都是function原型脸上的方法,用来改变function this的指向,并立即执行。 Call 的参数是一个个传入 Apply的参数是以数组的形式传入 Bind也能实现类似的方法,不过bind不是立即执行

Call 性能比 apply 好一些 特别在函数参数超过3的时候

rottenpen avatar May 31 '20 03:05 rottenpen

call & apply

call 和 apply 的区别是什么,哪个性能更好一些

  1. 使用方式不同
  2. 性能差异可忽略

Call ( F, V [ , argumentsList ] )

https://tc39.es/ecma262/#sec-call

https://tc39.es/ecma262/#sec-function.prototype.call

https://tc39.es/ecma262/#sec-function.prototype.apply

image

CreateListFromArrayLike

image

https://www.zhihu.com/question/61088667/answer/184598599

image

xgqfrms avatar Jun 02 '20 15:06 xgqfrms

两个方法的功能是一样的,都是为了改变函数的this指向,区别在于参数, 第一个参数都是this的指向,第二个参数有区别。 call从第二个参数开始,位数不固定,会原样传递给函数。 apply第二个参数只能传入数组、类数组、或者代下标的集合,然后会将数组解构后再把参数传递给函数。此处带下标的集合,可以理解为 {{0:'app',1:'app2',length:2} ,需要加length否则apply不识别 不过有了ES6的sprea operator后,参数是数组也可以用call了 fn.call(obj, ...[1,2,3]) call性能更好,少了将apply第二个参数解构的过程

soraly avatar Jun 23 '20 05:06 soraly

call、apply、bind的区别 作用:改变函数执行时的上下文 为什么要改变执行上下文? a对象又一个方法,由于某种原因b需要调用这个方法,那么b是单独拓展一个方法,还是借用a的方法呢,当然是借用a的方法,因为会减少内存占用

1、cal、apply、bind必须通过函数来调用,第一个参数为对象,若第一个参数为null或者undefined,则指向window 2、call和bind方法可以接收多个参数,apply方法只能接收2个参数,且第二个参数为数组或者伪数组 3、call和apply方法没有返回值(即返回undefined),bind方法返回一个原函数的拷贝,并具有指定的this值和初始参数 4、call和apply方法是立即调用,bind方法是稍后调用 参考:https://segmentfault.com/a/1190000018017796

tbapman avatar Mar 30 '21 07:03 tbapman

尤其是es6 引入了 Spread operator (延展操作符) 后,即使参数是数组,可以使用 call

let params = [1,2,3,4]
xx.call(obj, ...params)

然而这玩意要是被babel或者ts过了一遍变成es5全都变成了 xxx.call.apply(obj,params) image image

因为这里不确定你的call是原生的,还是自己写的call方法

rookieLink avatar Jul 04 '23 02:07 rookieLink