Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
zeroone001 opened this issue Apr 4, 2019 · 14 comments
Labels

Comments

@zeroone001
Copy link

zeroone001 commented Apr 4, 2019

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

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

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

@anyxl
Copy link

anyxl commented Apr 15, 2019

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

@chenzesam
Copy link

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

@francecil
Copy link

apply 需要对 argArray 做很多判断

@liaoyinglong
Copy link

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

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

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

@3460741663
Copy link

.call方法会立即执行!

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

@random-yang
Copy link

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

call:
image

apply:
image

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

@QZEming
Copy link

QZEming commented Mar 21, 2020

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

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

@zhenhong820
Copy link

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

@rottenpen
Copy link

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

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

@xgqfrms
Copy link

xgqfrms commented Jun 2, 2020

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

@soraly
Copy link

soraly commented Jun 23, 2020

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

@tbapman
Copy link

tbapman commented Mar 30, 2021

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

@rookieLink
Copy link

尤其是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方法

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests