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 相关文章推荐
IE8 兼容性问题(属性名区分大小写)
Jun 04 Javascript
网页前台通过js非法字符过滤代码(骂人的话等等)
May 26 Javascript
jQuery中获取Radio元素值的方法
Jul 02 Javascript
清除div下面的所有标签的方法
Feb 17 Javascript
深入理解关于javascript中apply()和call()方法的区别
Apr 12 Javascript
jQuery图片轮播实现并封装(一)
Dec 03 Javascript
详解微信小程序 页面跳转 传递参数
Dec 08 Javascript
JavaScript编写棋盘覆盖代码详解
Aug 28 Javascript
Vue的移动端多图上传插件vue-easy-uploader的示例代码
Nov 27 Javascript
p5.js绘制创意自画像
Nov 04 Javascript
jQuery实现简单评论功能
Aug 19 jQuery
JavaScript实现酷炫的鼠标拖尾特效
Feb 18 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数据库开发知多少
2006/10/09 PHP
mysql 的 like 问题,超强毕杀记!!!
2007/01/18 PHP
编写PHP程序检查字符串中的中文字符个数的实例分享
2016/03/17 PHP
Yii2中hasOne、hasMany及多对多关联查询的用法详解
2017/02/15 PHP
JavaScript 全面解析各种浏览器网页中的JS 执行顺序
2009/02/17 Javascript
搭建pomelo 开发环境
2014/06/24 Javascript
Javascript基于AJAX回调函数传递参数实例分析
2015/12/15 Javascript
JavaScript SHA512加密算法详细代码
2016/10/06 Javascript
jquery.multiselect多选下拉框实现代码
2016/11/11 Javascript
微信小程序url传参写变量的方法
2018/08/09 Javascript
Vue.js轮播图走马灯代码实例(全)
2019/05/08 Javascript
vue+element 模态框表格形式的可编辑表单实现
2019/06/07 Javascript
nodejs制作小爬虫功能示例
2020/02/24 NodeJs
windows如何把已安装的nodejs高版本降级为低版本(图文教程)
2020/12/14 NodeJs
[01:19]DOTA2城市挑战赛报名开始 开启你的城市传奇
2018/03/23 DOTA
跟老齐学Python之dict()的操作方法
2014/09/24 Python
Python 26进制计算实现方法
2015/05/28 Python
Python中的集合类型知识讲解
2015/08/19 Python
python中的错误处理
2016/04/10 Python
详解flask入门模板引擎
2018/07/18 Python
在Django中自定义filter并在template中的使用详解
2020/05/19 Python
Python中如何添加自定义模块
2020/06/09 Python
keras做CNN的训练误差loss的下降操作
2020/06/22 Python
python解包用法详解
2021/02/17 Python
解决TensorFlow训练模型及保存数量限制的问题
2021/03/03 Python
一份Java笔试题
2012/02/21 面试题
值类型与引用类型有什么不同?请举例说明?并分别列举几种相应的数据类型
2015/10/24 面试题
安全教育实施方案
2014/03/02 职场文书
成绩单公证书
2014/04/10 职场文书
预备党员学习十八届三中全会精神思想汇报
2014/09/13 职场文书
委托书的写法
2014/09/16 职场文书
教师批评与自我批评发言稿
2014/10/15 职场文书
安全隐患整改报告
2014/11/06 职场文书
党建工作汇报材料
2014/12/24 职场文书
物业保洁员管理制度
2015/08/05 职场文书
redis调用二维码时的不断刷新排查分析
2022/04/01 Redis