Array.prototype.concat不是通用方法反驳[译]


Posted in Javascript onSeptember 20, 2012

ECMAScript 5.1规范§15.4.4.4 中说到:

concat函数是有意设计成通用的;它并不要求它的this值必须得是个Array对象.因此,它可以被转移到其它类型的对象上作为方法来调用.

本文中的代码都使用了[]来作为Array.prototype的快捷方式.这已经是很常用的技巧了,虽然可读性差点:你通过一个对象实例访问到了Array.prototype上的方法.但是,这样的访问方式在现代的JavaScript引擎中非常之快,以至于我怀疑,说不定在这种调用方式下,这些JavaScript引擎可能已经不再创建数组实例了.本文中所有的例子都在Firefox和V8中尝试运行过.

让我们看一下concat到底是不是个通用方法:如果它是一个通用方法,则不管this的值是一个真实数组还是个类数组对象(拥有length属性,能通过索引访问每个元素),方法的返回结果都应该是一样的.我们首先尝试在数组上调用concat方法:

> ["hello"].concat(["world"]) 
["hello", "world"] > [].concat.call(["hello"], ["world"]) // 和上面的一样 
["hello", "world"]

然后,我们使用一个类数组对象来进行上面的连接操作.结果应该是一样的.

> [].concat.call({ 0: "hello", length: 1 }, ["world"]) 
[ { '0': 'hello', length: 1 }, 'world' ]

特殊变量arguments也是一个类数组对象.结果仍然不是我们所期望的:
> function f() { return [].concat.call(arguments, ["world"]) } 
> f("hello") 
[ { '0': 'hello' }, 'world' ]

真正的通用方法应该是这样的Array.prototype.push:

> var arrayLike = { 0: "hello", length: 1 }; 
> [].push.call(arrayLike, "world") 
2 
> arrayLike 
{ '0': 'hello', '1': 'world', length: 2 }

译者注:浏览器只是按照标准来实现,所以并不存在bug的问题.

Javascript 相关文章推荐
[对联广告] JS脚本类
Aug 27 Javascript
JavaScript 学习笔记(四)
Dec 31 Javascript
javascript replace()正则替换实现代码
Feb 26 Javascript
如何用JavaScript动态呼叫函数(两种方式)
May 03 Javascript
Checbox的操作含已选、未选及判断代码
Nov 07 Javascript
javascript结合Canvas 实现简易的圆形时钟
Mar 11 Javascript
JQuery实现带排序功能的权限选择实例
May 18 Javascript
获取JavaScript异步函数的返回值
Dec 21 Javascript
微信小程序 scroll-view实现上拉加载与下拉刷新的实例
Jan 21 Javascript
ionic中的$ionicPlatform.ready事件中的通用设置
Jun 11 Javascript
JavaScript实现短信倒计时60s
Oct 09 Javascript
vue防止花括号{{}}闪烁v-text和v-html、v-cloak用法示例
Mar 13 Javascript
JavaScript 用Node.js写Shell脚本[译]
Sep 20 #Javascript
一个简单的网站访问JS计数器 刷新1次加1次访问
Sep 20 #Javascript
javascript分页代码(当前页码居中)
Sep 20 #Javascript
javascript获取作用在元素上面的样式属性代码
Sep 20 #Javascript
一个基于jquery的文本框记数器
Sep 19 #Javascript
html中的input标签的checked属性jquery判断代码
Sep 19 #Javascript
基于jquery打造的百分比动态色彩条插件
Sep 19 #Javascript
You might like
浅谈PHP强制类型转换,慎用!
2013/06/06 PHP
laravel 5 实现模板主题功能(续)
2015/03/02 PHP
php中define用法实例
2015/07/30 PHP
PHP让网站移动访问更加友好方法
2019/02/14 PHP
JavaScript下申明对象的几种方法小结
2008/10/02 Javascript
JavaScript 对任意元素,自定义右键菜单的实现方法
2013/05/08 Javascript
javascript页面渲染速度测试脚本分享
2014/04/15 Javascript
javascript里绝对用的上的字符分割函数总结
2014/07/31 Javascript
JS去除iframe滚动条的方法
2015/04/01 Javascript
Jquery遍历Json数据的方法
2015/04/20 Javascript
js日期范围初始化得到前一个月日期的方法
2015/05/05 Javascript
JS实现仿FLASH效果的竖排导航代码
2015/09/15 Javascript
JavaScript测试工具之Karma-Jasmine的安装和使用详解
2015/12/03 Javascript
微信小程序 实现点击添加移除class
2017/06/12 Javascript
BootStrap TreeView使用实例详解
2017/11/01 Javascript
webpack+vue2构建vue项目骨架的方法
2018/01/09 Javascript
小程序红包雨的实现示例
2019/02/19 Javascript
小程序实现新用户判断并跳转激活的方法
2019/05/20 Javascript
[38:39]KG vs Mineski 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
python通过定义一个类实例作为ftp回调方法
2015/05/04 Python
python Matplotlib画图之调整字体大小的示例
2017/11/20 Python
python 列表,数组,矩阵两两转换tolist()的实例
2018/04/04 Python
在Python中增加和插入元素的示例
2018/11/01 Python
python中栈的原理及实现方法示例
2019/11/27 Python
python中sklearn的pipeline模块实例详解
2020/05/21 Python
CSS3实现多背景模拟动态边框的效果
2016/11/08 HTML / CSS
Html5 canvas实现粒子时钟的示例代码
2018/09/06 HTML / CSS
BONIA波尼亚新加坡官网:皮革手袋,鞋类和配件
2016/08/25 全球购物
加拿大最大的相机店:Henry’s
2017/05/17 全球购物
英国评分最高的女性剃须刀订阅盒:FFS Beauty
2018/01/25 全球购物
在求职信中如何凸显个人优势
2013/10/30 职场文书
大学活动策划书范文
2014/01/10 职场文书
销售员未完成销售业绩的检讨书
2014/10/12 职场文书
学校2016年圣诞节活动总结
2016/03/31 职场文书
详解python的内存分配机制
2021/05/10 Python