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 json 新手入门文档
Dec 03 Javascript
js判断FCKeditor内容是否为空的两种形式
May 14 Javascript
js的alert样式如何更改如背景颜色
Jan 22 Javascript
jquery获取及设置outerhtml的方法
Mar 09 Javascript
js数组常见操作及数组与字符串相互转化实例详解
Nov 10 Javascript
javascript设计模式Constructor(构造器)模式
Aug 19 Javascript
值得分享的bootstrap table实例
Sep 22 Javascript
3种不同的ContextMenu右键菜单实现代码
Nov 03 Javascript
Angular使用ng-messages与PHP进行表单数据验证
Dec 28 Javascript
MUI 实现侧滑菜单及其主体部分上下滑动的方法
Jan 25 Javascript
解决layer弹出层msg的文字不显示的问题
Sep 11 Javascript
JS如何寻找数组中心索引过程解析
Jun 01 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 模拟POST|GET操作实现代码
2010/07/20 PHP
php学习之 数组声明
2011/06/09 PHP
php模板函数 正则实现代码
2012/10/15 PHP
Laravel与CI框架中截取字符串函数
2016/05/08 PHP
PHP实现小偷程序实例
2016/10/31 PHP
PHP网页安全认证的实例详解
2017/09/28 PHP
Laravel5.1 框架Middleware中间件基本用法实例分析
2020/01/04 PHP
基于JQuery实现的类似购物商城的购物车
2011/12/06 Javascript
关于jQuery参考实例 1.0 jQuery的哲学
2013/04/07 Javascript
基于NodeJS的前后端分离的思考与实践(二)模版探索
2014/09/26 NodeJs
javascript实现滑动解锁功能
2014/12/31 Javascript
JavaScript控制网页层收起和展开效果的方法
2015/04/15 Javascript
javascript+html5实现仿flash滚动播放图片的方法
2015/04/27 Javascript
JS实现超简单的鼠标拖动效果
2015/11/02 Javascript
JavaScript黑洞数字之运算路线查找算法(递归算法)实例
2016/01/28 Javascript
Vue响应式添加、修改数组和对象的值
2017/03/20 Javascript
微信小程序 商城开发(ecshop )简单实例
2017/04/07 Javascript
vue2+el-menu实现路由跳转及当前项的设置方法实例
2017/11/07 Javascript
vue中使用refs定位dom出现undefined的解决方法
2017/12/21 Javascript
js实现各浏览器全屏代码实例
2018/07/03 Javascript
详解Vue+axios+Node+express实现文件上传(用户头像上传)
2018/08/10 Javascript
解决angularjs中同步执行http请求的方法
2018/08/13 Javascript
用VueJS写一个Chrome浏览器插件的实现方法
2019/02/27 Javascript
js实现图片局部放大效果详解
2019/03/18 Javascript
[16:56]教你分分钟做大人:司夜刺客
2014/10/30 DOTA
详谈python http长连接客户端
2017/06/12 Python
python得到windows自启动列表的方法
2018/10/14 Python
用Pycharm实现鼠标滚轮控制字体大小的方法
2019/01/15 Python
django 利用Q对象与F对象进行查询的实现
2020/05/15 Python
python利用pytesseract 实现本地识别图片文字
2020/12/14 Python
python urllib和urllib3知识点总结
2021/02/08 Python
CSS3中的opacity属性使用教程
2015/08/19 HTML / CSS
护士求职自荐信范文
2014/03/19 职场文书
给客户的检讨书
2014/12/21 职场文书
2015年助残日活动总结
2015/03/27 职场文书
2015年语文教师工作总结
2015/05/25 职场文书