call 和 apply 和有什么不一样?
问:
使用 Function.prototype.apply() 和 Function.prototype.call() 调用函数有什么区别?
var func = function() {alert('hello!');
};
func.apply(); 与 func.call();
上述两种方法之间是否存在性能差异?什么时候最好使用 call 而不是 apply,反之亦然?
答1:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
不同之处在于 apply 允许您使用 arguments 作为数组调用函数; call 要求明确列出参数。一个有用的助记符是 “A 表示 a 射线,C 表示 comma。”
请参阅 MDN 关于 apply 和 call 的文档。
伪语法:
theFunction.apply(valueForThis, arrayOfArgs)
theFunction.call(valueForThis, arg1, arg2, …)
从 ES6 开始,还可以使用 spread 数组与 call 函数一起使用,您可以看到兼容性 here。
示例代码:
function theFunction(name,professional) { console.log(“我叫”+name+“,我是”+professional+“。”); } theFunction(“约翰”, “消防员”); theFunction.apply(undefined, [“Susan”, “学校老师”]); theFunction.call(undefined, “克劳德”, “数学家”); theFunction.call(undefined, …[“Matthew”, “physicist”]); // 与扩展运算符一起使用
要添加的一件事是 args 必须是数字数组 ([])。关联数组 ({}) 将不起作用。
@KevinSchroeder:在 javascript 中,[] 被称为 array,{} 被称为 object。
我经常忘记哪个需要一个数组,哪个需要你列出参数。我曾经记得的一个技巧是,如果方法的第一个字母以 a 开头,那么它需要一个数组,即一个应用数组
@SAM 使用 call 而不是普通的函数调用只有在您需要更改函数调用的 this 值时才有意义。一个示例(将函数参数对象转换为数组):Array.prototype.slice.call(arguments) 或 [].slice.call(arguments)。 apply 如果您在数组中有参数,例如在调用具有(几乎)相同参数的另一个函数的函数中,则 apply 是有意义的。 建议 如果可以满足您的需要,请使用普通函数调用 funcname(arg1),并在您真正需要的特殊场合保存 call 和 apply他们。
@KunalSingh call 和 apply 都有两个参数。 apply' and call 函数的第一个参数必须是所有者对象,第二个参数将分别是数组或逗号分隔的参数。如果您将 null 或 undefined 作为第一个参数传递,那么在非严格模式下,它们将被替换为全局对象,即 window
答2:
HuntsBot周刊–不定时分享成功产品案例,学习他们如何成功建立自己的副业–huntsbot.com
K. Scott Allen 对此有 a nice writeup。
基本上,它们在处理函数参数的方式上有所不同。
apply() 方法与 call() 相同,只是 apply() 需要一个数组作为第二个参数。该数组表示目标方法的参数。”
所以:
// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
apply() 和 call() 的第二个参数是可选的,不是必需的。
第一个参数也不是必需的。
@Ikrom,第一个参数不是 call 所必需的,而是 apply 所必需的
答3:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
要回答有关何时使用每个函数的部分,如果您不知道要传递的参数数量,或者如果它们已经在数组或类似数组的对象中(如 arguments 对象),请使用 apply转发您自己的参数。否则使用 call,因为不需要将参数包装在数组中。
f.call(thisObject, a, b, c); // Fixed number of argumentsf.apply(thisObject, arguments); // Forward this function's argumentsvar args = [];
while (...) {args.push(some_value());
}
f.apply(thisObject, args); // Unknown number of arguments
当我不传递任何参数时(如您的示例),我更喜欢 call,因为我正在 调用该函数。 apply 表示您正在将该函数应用到(不存在的)参数。
应该没有任何性能差异,除非您使用 apply 并将参数包装在一个数组中(例如 f.apply(thisObject, [a, b, c]) 而不是 f.call(thisObject, a, b, c))。我没有测试过它,所以可能会有差异,但它会非常特定于浏览器。如果您还没有数组中的参数,call 可能会更快,如果有的话,apply 可能会更快。
答4:
huntsbot.com汇聚了国内外优秀的初创产品创意,可按收入、分类等筛选,希望这些产品与实践经验能给您带来灵感。
这是一个很好的助记符。 Apply 使用数组并且总是使用一两个参数。当您使用 Call 时,您必须计算参数的数量。
有用的助记符就在那里!我会将“一个或两个参数”更改为“最多两个参数”,因为 apply 的第一个或第二个参数都不是必需的。我不确定为什么会在没有参数的情况下调用 apply 或 call。似乎有人试图找出这里的原因stackoverflow.com/questions/15903782/…
答5:
huntsbot.com洞察每一个产品背后的需求与收益,从而捕获灵感
虽然这是一个老话题,但我只想指出 .call 比 .apply 稍快。我不能告诉你确切的原因。
参见 jsPerf,http://jsperf.com/test-call-vs-apply/3
[UPDATE!]
Douglas Crockford 简要提到了两者之间的差异,这可能有助于解释性能差异… http://youtu.be/ya4UHuXNygM?t=15m52s
Apply 接受一个参数数组,而 Call 接受零个或多个单独的参数!啊哈哈!
.apply(this, […])
.call(this, param1, param2, param3, param4…)
这取决于函数对参数/数组的作用,如果不需要处理数组,是否需要更少的时间?
有趣的是,即使没有数组,调用仍然要快得多。 jsperf.com/applyvscallvsfn2
@JoshMc 那将是非常特定于浏览器的。在 IE 11 中,我的应用速度是通话速度的两倍。
1. 创建一个新数组意味着垃圾收集器需要在某个时候清理它。 2. 使用解引用访问数组中的项目比直接访问变量(参数)效率低。 (我相信这就是 kmatheny 所说的“解析”,这实际上是完全不同的东西。)但是我的论点都没有解释 jsperf。这必须与引擎对这两个函数的实现有关,例如,如果没有传递,它们可能会创建一个空数组。
感谢您分享测试和视频
答6:
一个优秀的自由职业者,应该有对需求敏感和精准需求捕获的能力,而huntsbot.com提供了这个机会
遵循 Closure: The Definitive Guide by Michael Bolin 的摘录。它可能看起来有点冗长,但它充满了很多洞察力。来自“附录 B. 经常被误解的 JavaScript 概念”:
调用函数时 this 指的是什么
当调用 foo.bar.baz() 形式的函数时,对象 foo.bar 被称为接收者。当函数被调用时,接收者被用作 this 的值:
var obj = {};
obj.value = 10;
/** @param {...number} additionalValues */
obj.addValues = function(additionalValues) {for (var i = 0; i < arguments.length; i++) {this.value += arguments[i];}return this.value;
};
// Evaluates to 30 because obj is used as the value for 'this' when
// obj.addValues() is called, so obj.value becomes 10 + 20.
obj.addValues(20);
如果调用函数时没有明确的接收者,则全局对象成为接收者。如第 47 页的“goog.global”中所述,当 JavaScript 在 Web 浏览器中执行时,window 是全局对象。这导致了一些令人惊讶的行为:
var f = obj.addValues;
// Evaluates to NaN because window is used as the value for 'this' when
// f() is called. Because and window.value is undefined, adding a number to
// it results in NaN.
f(20);
// This also has the unintentional side effect of adding a value to window:
alert(window.value); // Alerts NaN
即使 obj.addValues 和 f 引用相同的函数,它们在调用时的行为也会有所不同,因为接收者的值在每次调用中都不同。因此,在调用引用 this 的函数时,确保 this 在调用时具有正确的值非常重要。需要明确的是,如果函数体中没有引用 this,那么 f(20) 和 obj.addValues(20) 的行为将是相同的。
因为函数是 JavaScript 中的一等对象,所以它们可以有自己的方法。所有函数都有方法 call() 和 apply(),它们可以在调用函数时重新定义接收者(即 this 引用的对象)。方法签名如下:
/**
* @param {*=} receiver to substitute for 'this'
* @param {...} parameters to use as arguments to the function
*/
Function.prototype.call;
/**
* @param {*=} receiver to substitute for 'this'
* @param {Array} parameters to use as arguments to the function
*/
Function.prototype.apply;
请注意,call() 和 apply() 之间的唯一区别是 call() 将函数参数作为单独的参数接收,而 apply() 将它们作为单个数组接收:
// When f is called with obj as its receiver, it behaves the same as calling
// obj.addValues(). Both of the following increase obj.value by 60:
f.call(obj, 10, 20, 30);
f.apply(obj, [10, 20, 30]);
以下调用是等效的,因为 f 和 obj.addValues 指的是同一个函数:
obj.addValues.call(obj, 10, 20, 30);
obj.addValues.apply(obj, [10, 20, 30]);
但是,由于 call() 和 apply() 都没有使用自己的接收者的值来代替未指定的接收者参数,因此以下内容将不起作用:
// Both statements evaluate to NaN
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);
调用函数时,this 的值永远不能是 null 或 undefined。当 null 或 undefined 作为接收器提供给 call() 或 apply() 时,全局对象将用作接收器的值。因此,前面的代码同样具有向全局对象添加一个名为 value 的属性的不良副作用。
将函数视为不知道分配给它的变量可能会有所帮助。这有助于强化这样的想法,即 this 的值将在调用函数时而不是在定义函数时绑定。
提取结束。
请注意,additionalValues 未在 obj.addValues 正文中引用
我知道你在回答这个问题,但想补充一点:你可以在定义 f 时使用 bind。 var f = obj.addValues; 变为 var f = obj.addValues.bind(obj),现在 f(20) 无需每次都使用 call 或 apply 即可工作。
我知道这不是你写的,但你确实强调了书中相关的文字和示例,我非常感激。他们非常有帮助。
答7:
huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式
有时,一个对象借用另一个对象的功能很有用,这意味着借用的对象只是简单地执行借出的功能,就好像它是自己的一样。
一个小代码示例:
var friend = {car: false,lendCar: function ( canLend ){this.car = canLend;}}; var me = {car: false,gotCar: function(){return this.car === true;}
};console.log(me.gotCar()); // falsefriend.lendCar.call(me, true); console.log(me.gotCar()); // truefriend.lendCar.apply(me, [false]);console.log(me.gotCar()); // false
这些方法对于赋予对象临时功能非常有用。
想知道如何查看console.log的人请查看:What is console.log and how do I use it?
答8:
保持自己快人一步,享受全网独家提供的一站式外包任务、远程工作、创意产品订阅服务–huntsbot.com
调用、应用和绑定的另一个例子。 Call 和 Apply 之间的区别很明显,但 Bind 的工作方式如下:
Bind 返回一个可以执行的函数实例 第一个参数是 ‘this’ 第二个参数是逗号分隔的参数列表(如调用)
}
function Person(name) {this.name = name;
}
Person.prototype.getName = function(a,b) { return this.name + " " + a + " " + b;
}var reader = new Person('John Smith');reader.getName = function() {// Apply and Call executes the function and returns value// Also notice the different ways of extracting 'getName' prototypevar baseName = Object.getPrototypeOf(this).getName.apply(this,["is a", "boy"]);console.log("Apply: " + baseName);var baseName = Object.getPrototypeOf(reader).getName.call(this, "is a", "boy"); console.log("Call: " + baseName);// Bind returns function which can be invokedvar baseName = Person.prototype.getName.bind(this, "is a", "boy"); console.log("Bind: " + baseName());
}reader.getName();
/* Output
Apply: John Smith is a boy
Call: John Smith is a boy
Bind: John Smith is a boy
*/
答9:
huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式
我想展示一个示例,其中使用了“valueForThis”参数:
Array.prototype.push = function(element) {/*Native code*, that uses 'this' this.put(element);*/
}
var array = [];
array.push(1);
array.push.apply(array,[2,3]);
Array.prototype.push.apply(array,[4,5]);
array.push.call(array,6,7);
Array.prototype.push.call(array,8,9);
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
*详情:http://es5.github.io/#x15.4.4.7
答10:
huntsbot.com全球7大洲远程工作机会,探索不一样的工作方式
Call() 接受逗号分隔的参数,例如:
.call(scope, arg1, arg2, arg3)
并且 apply() 接受一个参数数组,例如:
.apply(scope, [arg1, arg2, arg3])
这里还有几个使用示例:http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/
// call() === 逗号分隔的参数 (arguments-list) .call(this, args1, args2, args3, ...) // apply() === 参数数组 (array-items) .应用(这个,[arr0,arr1,arr2,...])
答11:
huntsbot.com – 高效赚钱,自由工作
从 the MDN docs on Function.prototype.apply() :
apply() 方法使用给定的 this 值和作为数组(或类似数组的对象)提供的参数调用函数。语法 fun.apply(thisArg, [argsArray])
从 the MDN docs on Function.prototype.call() :
call() 方法使用给定的 this 值和单独提供的参数调用函数。语法 fun.call(thisArg[, arg1[, arg2[, …]]])
从 Function.apply and Function.call in JavaScript :
apply() 方法与 call() 相同,只是 apply() 需要一个数组作为第二个参数。该数组表示目标方法的参数。
代码示例:
var doSomething = function() { var arr = []; for(i in arguments) { if(typeof this[arguments[i]] !== ‘undefined’) { arr.push(this[arguments[i]]); } } 返回 arr; } var output = function(position, obj) { document.body.innerHTML += 'output ’ + position + ‘’ + JSON.stringify(obj) + ‘\n\n< br><小时>’; } 输出(1,doSomething(“一”,“二”,“二”,“一”));输出(2,doSomething.apply({一:‘史蒂文’,二:‘简’},[‘一’,‘二’,‘二’,‘一’]));输出(3,doSomething.call({一个:‘史蒂文’,两个:‘简’},‘一个’,‘两个’,‘两个’,‘一个’));
另见this Fiddle。
打造属于自己的副业,开启自由职业之旅,从huntsbot.com开始!
原文链接:https://www.huntsbot.com/qa/yOnr/what-is-the-difference-between-call-and-apply?lang=zh_CN&from=csdn
huntsbot.com高效搞钱,一站式跟进超10+任务平台外包需求
call 和 apply 和有什么不一样?相关推荐
- Kotlin let、with、run、apply、also函数的使用
let,with,run,apply,also 是内联扩展函数 下面是自己使用的心的如果有错的地方希望给予指正谢谢 这几个主要用来简化操作,使得代码可读性提高 ,下面列举项目中使用效果 1 let 先 ...
- JS中的call()方法和apply()方法用法总结
1. 每个函数都包含两个非继承而来的方法:call()方法和apply()方法. 2. 相同点:这两个方法的作用是一样的. 都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖 ...
- python dataframe取某行某列_pandas dataframe.apply() 实现对某一行/列进行处理获得一个新行/新列...
重点: dataframe.apply(function,axis)对一行或一列做出一些操作(axis=1则为对某一列进行操作,此时,apply函数每次将dataframe的一行传给function, ...
- Angular的ChangeDetectorRef.detectChanges()实现angularJS的$apply()方法,强制刷新数据渲染
在Javascript代码里,都是按照一定顺序来执行的,当轮到一个代码片段执行的时候,浏览器就只会去执行当前的片段,不会做任何其他的事情.所以有时候一些做得不是很好的网页,当点击了某个东西之后会卡住, ...
- javascript的call()方法与apply()方法的理解
先看一段代码 function cat() {} cat.prototype={food:'fish',say:function () {console.log('I love '+this.food ...
- 函数的四种调用模式.上下文调用.call.apply
闭包:函数就是一个闭包,一个封闭的作用域; 返回函数,要返回多个函数就用一个对象封装一下, 立即执行函数+return 回调函数 JS动态创建的DOM,不会被搜索引擎抓取,对SEO不友好. /*win ...
- 微信小程序之apply和call ( 附示例代码和注释讲解) apply call bind
微信小程序开发交流qq群 173683895 相同点:作用是一样的,它们能劫持另外一个对象的方法,继承另外一个对象的属性: js中的call(), apply()和bind()是Function. ...
- apply call bind 简介
Function.prototype.call(thisArg [, arg1, arg2, ...]) call() 简述 call() 方法 调用一个函数, 其具有一个指定的 this 值和分别地 ...
- The Apply method of function object
2019独角兽企业重金招聘Python工程师标准>>> http://webreference.com As explained in the previous page, Java ...
- JS学习笔记之call、apply的用法
1.call和apply的区别 call和apply唯一的区别是传入参数的形式不同. apply接受两个参数,第一个参数指定了函数体内this对象的指向,第二个参数为一个带下标的集合,可以是数组,也可 ...
最新文章
- pythonista3使用说明_Pythonista中文文档:sound
- vue 源码学习(一) 目录结构和构建过程简介 1
- WORD如何隐藏选中内容?
- 【学习率调整】学习率衰减之周期余弦退火 (cyclic cosine annealing learning rate schedule)
- 华中数控预计继续亏损 拟靠关联交易增收存疑
- 计蒜之道2015程序设计大赛初赛第三场——腾讯手机地图
- 使用BigDecimal时,报NumberFormatException
- UVA11021 Tribles
- opboot怎么刷入固件_OPPO手机怎么进行系统(固件)升级?(附四种方法)
- android人脸抠图,人脸框抠图如何实现
- java使字符串转二维码
- linux c 删除文件,linux c remove 删除文件或目录函数
- Linux查找之find/df/du命令
- Distributed System 基础(四)隐私性(Privacy)
- 领导驾驶舱大数据平台的实施流程
- EPS创建三维模型-(osgb数据在EPS中的转换数据)
- 是谁在为加速网络智能化落地打造开放、融合、端到端平台?
- 软件自动化测试——入门、进阶与实战
- a类计算机期刊,中国计算机学会推荐国际学术刊物(人工智能与模式识别)
- 如何把小米和计算机共享,小米盒子局域网共享方法 Windows7系统共享图文教程