JavaScript 中使用 Call 或 Apply 扩展的好处是什么?

2016-01-23 10:39:36 +08:00
 eniac0001

例如对 String 添加 reverse 方法,一般是这样写:

String.prototype.reverse = function() {
return Array.prototype.reverse.apply(this.split("")).join();
}

可不可以这样写:

String.prototype.reverse = function() {
return this.split("").reverse().join();
}

上面的写法比下面的写法有什么好处呢?

3684 次点击
所在节点    JavaScript
21 条回复
runcelim
2016-01-23 10:56:57 +08:00
String 通过 apply 或 call 借用 Array 的 reverse 实现方法
sagnitude
2016-01-23 11:47:01 +08:00
为了写起来方便,自由度更大。比如 func.apply(null, arguments),改变 this ,使用 arguments ,还有 Array.prototype.slice.call(arguments),强行调用其他对象的方法,

另外的区别就是 apply 比 call 慢, call 比直接调用慢, bind 方法比这些都慢
另外, string 的 reverse 方法,用 for 循环比这两个都快
另外, join 方法不带参数默认使用逗号作为分隔符
Keita1314
2016-01-23 12:27:56 +08:00
1 是指定 this
2 是有些情况,比如类数组对象,根本就没有 reverse 这个方法可以调用,只能通过借用 Array 的方法来实现
oott123
2016-01-23 13:21:33 +08:00
感觉在 LZ 给的例子里,完全没必要用 Array.prototype.reverse.call
倒是像这样的场景可能需要:
str = "Hello world!"
Array.prototype.slice.call(str, 1, 3).join('')
> "el"
shyling
2016-01-23 13:31:33 +08:00
1 。想改变 this 时
2 。例如想遍历 NodeList 时用 Array.prototype.forEach.call
3 。用 arguments 时配合 apply
breeswish
2016-01-23 14:16:03 +08:00
楼主给的例子里上面写法没什么用..
BOYPT
2016-01-23 14:24:50 +08:00
最主要就是改变调用栈。不过如果用了框架比如 jquery.proxy, _.bind 之类的封装就可以不需要用 apply call 了,一般来说。原生党比较最爱。
iyangyuan
2016-01-23 14:49:40 +08:00
复用
eniac0001
2016-01-23 16:45:15 +08:00
eniac0001
2016-01-23 16:47:04 +08:00
@iyangyuan 谢谢!
eniac0001
2016-01-23 16:48:21 +08:00
@oott123 @breeswish Sorry ,我例子的问题,怪不得看了半天没看出明显的差异!
eniac0001
2016-01-23 16:48:53 +08:00
@BOYPT 谢谢!
eniac0001
2016-01-23 16:50:49 +08:00
@sagnitude 考虑的很仔细,多谢!
ChefIsAwesome
2016-01-23 16:58:53 +08:00
apply 能用数组的形式给函数传参,这个特性很有用的。
有些人设计的函数是这样的
`function (arg1, arg2, arg3, ...) { }`
参数数量不限,但是必须一个一个写。如果你的参数是从其他地方以数组的形式过来的,那用 apply 就很方便了。
chemzqm
2016-01-23 17:00:50 +08:00
改变内部 this ,做工具库经常用的 ,有一个特别常用的,将 NodeList 转化为数组

Array.prototype.silce.call(document.querySelector('.item'))

用 new Array 创建性能更好,就是代码多点
alsotang
2016-01-23 20:31:50 +08:00
所以楼上各位大大,楼主列举的那两种写法,到底上面那种好在哪里呢?
breeswish
2016-01-23 21:54:36 +08:00
@oott123 其实这种场景也可以直接 #String.slice 的 :-)
lxrmido
2016-01-23 22:58:10 +08:00
@alsotang

没好处
eniac0001
2016-01-24 10:26:19 +08:00
@alsotang 列举的两个例子不好,可以参考 @oott123 的例子研究一下。。。
oott123
2016-01-24 10:33:06 +08:00
@eniac0001 我的例子也不好, @breeswish 说得对,在新标准里 String 已经有 slice 方法了…不过你可以当他没有 hhhh

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/252790

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX