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 页面执行时间计算代码
Mar 04 Javascript
jquery 关键字“拖曳搜索”之“拖曳”以及 图片“提示自适应放大”效果 的实现
Apr 18 Javascript
让alert不出现弹窗的两种方法
May 18 Javascript
使用node.js 获取客户端信息代码分享
Nov 26 Javascript
解决WordPress使用CDN后博文无法评论的错误
Dec 15 Javascript
js querySelector() 使用方法
Dec 21 Javascript
jquery动态赋值id与动态取id方法示例
Aug 21 jQuery
jQuery实现定时隐藏对话框的方法分析
Feb 12 jQuery
jQuery实现新闻播报滚动及淡入淡出效果示例
Mar 23 jQuery
webpack4与babel配合使es6代码可运行于低版本浏览器的方法
Oct 12 Javascript
vue中子组件传递数据给父组件的讲解
Jan 27 Javascript
微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
May 22 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
火车采集器 免费版使出收费版本功能实现原理
2009/09/17 PHP
初品cakephp 入门基础
2012/02/16 PHP
thinkphp的静态缓存用法分析
2014/11/29 PHP
Symfony学习十分钟入门经典教程
2016/02/03 PHP
PHP微信开发之查询微信精选文章
2016/06/23 PHP
php安全配置记录和常见错误梳理(总结)
2017/03/28 PHP
PHP7 list() 函数修改
2021/03/09 PHP
Javascript使用post方法提交数据实例
2015/08/03 Javascript
JavaScript判断表单为空及获取焦点的方法
2016/02/12 Javascript
基于jQuery日历插件制作日历
2016/03/11 Javascript
Angularjs处理页面闪烁的解决方法
2017/03/09 Javascript
基于Vue实现后台系统权限控制的示例代码
2017/08/29 Javascript
Node之简单的前后端交互(实例讲解)
2017/11/14 Javascript
vue中的计算属性实例详解
2018/09/19 Javascript
在vue中使用express-mock搭建mock服务的方法
2018/11/07 Javascript
VsCode与Node.js知识点详解
2019/09/05 Javascript
JavaScript实现移动端带transition动画的轮播效果
2020/03/24 Javascript
微信小程序实现弹框效果
2020/05/26 Javascript
JS轮播图的实现方法
2020/08/24 Javascript
js实现有趣的倒计时效果
2021/01/19 Javascript
Python中的类学习笔记
2014/09/23 Python
Pandas删除数据的几种情况(小结)
2019/06/21 Python
对django后台admin下拉框进行过滤的实例
2019/07/26 Python
Python如何测试stdout输出
2020/08/10 Python
python 动态渲染 mysql 配置文件的示例
2020/11/20 Python
五款漂亮的纯CSS3动画按钮的实例教程
2014/11/21 HTML / CSS
HTML5未来发展趋势
2016/02/01 HTML / CSS
香港永安旅游网:Wing On Travel
2017/04/10 全球购物
俄罗斯奢侈品牌衣服、鞋子和配饰的在线商店:INTERMODA
2020/07/17 全球购物
自学考试自我鉴定范文
2013/09/26 职场文书
法律六进活动方案
2014/03/13 职场文书
2014年五四青年节活动方案
2014/03/29 职场文书
关于中国梦的演讲稿
2014/04/23 职场文书
创先争优个人总结
2015/03/04 职场文书
如何使用Maxwell实时同步mysql数据
2021/04/08 MySQL
Ajax异步刷新功能及简单案例
2021/11/20 Javascript