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 相关文章推荐
Javascript 个人笔记(没有整理,很乱)
Jul 07 Javascript
在html页面中包含共享页面的方法
Oct 24 Javascript
javascript基础知识大集锦(二) 推荐收藏
Jan 13 Javascript
js分解url参数(面向对象-极简主义法应用)
Aug 09 Javascript
怎样在JavaScript里写一个swing把数据插入数据库
Dec 10 Javascript
JQuery加载图片自适应固定大小的DIV
Sep 12 Javascript
浅析JavaScript中的typeof运算符
Nov 30 Javascript
js使用循环清空某个div中的input标签值
Sep 29 Javascript
JS HTML5实现拖拽移动列表效果
Aug 27 Javascript
SelecT下拉框选中和取值的解决方法
Nov 22 Javascript
vue.js路由跳转详解
Aug 28 Javascript
js调用设备摄像头的方法
Jul 19 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
CI框架入门之MVC简单示例
2016/11/21 PHP
Iframe thickbox2.0使用的方法
2009/03/05 Javascript
分享精心挑选的23款美轮美奂的jQuery 图片特效插件
2012/08/14 Javascript
js 取时间差去掉周六周日实现代码
2012/12/25 Javascript
javascript中的缓动效果实现程序
2012/12/29 Javascript
javascript转换日期字符串为Date日期对象的方法
2015/02/13 Javascript
学习javascript的闭包,原型,和匿名函数之旅
2015/10/18 Javascript
第一次接触JS require.js模块化工具
2016/04/17 Javascript
JavaScript中函数声明与函数表达式的区别详解
2016/08/18 Javascript
JS动态加载脚本并执行回调操作
2016/08/24 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
2017/01/04 Javascript
基于LayUI分页和LayUI laypage分页的使用示例
2017/08/02 Javascript
javascript中UMD规范的代码推演
2018/08/29 Javascript
利用原生的JavaScript实现简单拼图游戏
2018/11/18 Javascript
浅谈vue后台管理系统权限控制思考与实践
2018/12/19 Javascript
Node.js+ELK日志规范的实现
2019/05/23 Javascript
微信小程序入口场景的问题集合与相关解决方法
2019/06/26 Javascript
JavaScript Window窗口对象属性和使用方法
2020/01/19 Javascript
vue项目中自定义video视频控制条的实现代码
2020/04/26 Javascript
vue输入框使用模糊搜索功能的实现代码
2020/05/26 Javascript
JS实现简单打字测试
2020/06/24 Javascript
[05:34]2014DOTA2国际邀请赛中国区预选赛精彩TOPPLAY第二弹
2014/06/25 DOTA
python多线程编程中的join函数使用心得
2014/09/02 Python
Python设计模式之观察者模式简单示例
2018/01/10 Python
Python抽象和自定义类定义与用法示例
2018/08/23 Python
python 实现GUI(图形用户界面)编程详解
2019/07/17 Python
使用python3批量下载rbsp数据的示例代码
2019/12/20 Python
python TCP包注入方式
2020/05/05 Python
HTML5标签小集
2011/08/02 HTML / CSS
static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?
2015/02/22 面试题
新学期开学演讲稿
2014/05/24 职场文书
空气环保标语
2014/06/12 职场文书
个人求职意向书
2015/05/11 职场文书
2016教师六五普法学习心得体会
2016/01/21 职场文书
入伍志愿书怎么写?
2019/07/19 职场文书
WIN10使用IIS部署ftp服务器详细教程
2022/08/05 Servers