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 相关文章推荐
FireFox中textNode分片的问题
Apr 10 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
Oct 24 Javascript
JQuery radio(单选按钮)操作方法汇总
Apr 15 Javascript
JavaScript中的getTime()方法使用详解
Jun 10 Javascript
web前端开发JQuery常用实例代码片段(50个)
Aug 28 Javascript
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
Feb 23 Javascript
微信小程序 wx.request(OBJECT)发起请求详解
Oct 13 Javascript
vue-router路由简单案例介绍
Feb 21 Javascript
React如何将组件渲染到指定DOM节点详解
Sep 08 Javascript
Vue实现仿iPhone悬浮球的示例代码
Mar 13 Javascript
JS监听组合按键思路及实现过程
Apr 17 Javascript
vue 动态组件(component :is) 和 dom元素限制(is)用法说明
Sep 04 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 编程安全性小结
2010/01/08 PHP
PHP中的函数嵌套层数限制分析
2011/06/13 PHP
XAMPP安装与使用方法详细解析
2013/11/27 PHP
在 Laravel 中 “规范” 的开发短信验证码发送功能
2017/10/26 PHP
JS获取IUSR_机器名和IWAM_机器名帐号的密码
2006/12/06 Javascript
javascript 实现父窗口引用弹出窗口的值的脚本
2007/08/07 Javascript
浏览器脚本兼容 文本框中,回车键触发事件的兼容
2010/06/21 Javascript
js 弹出菜单/窗口效果
2011/10/30 Javascript
javascript判断ie浏览器6/7版本加载不同样式表的实现代码
2011/12/26 Javascript
解析JavaScript中的字符串类型与字符编码支持
2016/06/24 Javascript
bootstrap读书笔记之CSS组件(上)
2016/10/17 Javascript
Node.js Express 框架 POST方法详解
2017/01/23 Javascript
浅谈js中的变量名和函数名重名
2017/02/13 Javascript
JavaScript Canvas绘制圆形时钟效果
2020/08/20 Javascript
用nodejs实现json和jsonp服务的方法
2017/08/25 NodeJs
vue 微信授权登录解决方案
2018/04/10 Javascript
js中事件对象和事件委托的介绍
2019/01/21 Javascript
RxJS的入门指引和初步应用
2019/06/15 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
2019/08/02 jQuery
layer扩展打开/关闭动画的方法
2019/09/23 Javascript
利用Python破解验证码实例详解
2016/12/08 Python
Python中enumerate()函数编写更Pythonic的循环
2018/03/06 Python
Python构建图像分类识别器的方法
2019/01/12 Python
python利用pytesseract 实现本地识别图片文字
2020/12/14 Python
Pytorch1.5.1版本安装的方法步骤
2020/12/31 Python
CSS3绘制不规则图形的一些方法示例
2015/11/07 HTML / CSS
英国领先的瓷砖专家:Walls and Floors
2018/04/27 全球购物
意大利值得信赖的在线超级药房:PillolaStore
2020/02/05 全球购物
中文系学生自荐信范文
2013/11/13 职场文书
企业内控岗位的职责
2014/02/07 职场文书
初中班主任评语
2014/04/24 职场文书
2015年爱牙日活动总结
2015/03/23 职场文书
幽灵公主观后感
2015/06/09 职场文书
禁毒主题班会教案
2015/08/14 职场文书
手写Spirit防抖函数underscore和节流函数lodash
2022/03/22 Javascript
angular4实现带搜索的下拉框
2022/03/25 Javascript