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编程起步(第四课)
Jan 10 Javascript
jquery的extend和fn.extend的使用说明
Jan 09 Javascript
JavaScript快速检测浏览器对CSS3特性的支持情况
Sep 26 Javascript
JS实现淘宝支付宝网站的控制台菜单效果
Sep 28 Javascript
JS判断是否长按某一键的方法
Mar 02 Javascript
express文件上传中间件Multer详解
Oct 24 Javascript
微信小程序 数据交互与渲染实例详解
Jan 21 Javascript
javascript观察者模式实现自动刷新效果
Sep 05 Javascript
利用SpringMVC过滤器解决vue跨域请求的问题
Feb 10 Javascript
详解微信小程序-canvas绘制文字实现自动换行
Apr 26 Javascript
微信小程序自定义组件传值 页面和组件相互传数据操作示例
May 05 Javascript
vue项目,代码提交至码云,iconfont的用法说明
Jul 30 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
乐信RP2100的电路分析和打磨
2021/03/02 无线电
php adodb介绍
2009/03/19 PHP
PHP 函数学习简单小结
2010/07/08 PHP
CodeIgniter模板引擎使用实例
2014/07/15 PHP
php用ini_get获取php.ini里变量值的方法
2015/03/04 PHP
PHP获取一年有几周以及每周开始日期和结束日期
2015/08/06 PHP
PHP中SSO Cookie登录分析和实现
2015/11/06 PHP
CI框架数据库查询之join用法分析
2016/05/18 PHP
PHP控制反转(IOC)和依赖注入(DI)
2017/03/13 PHP
js的with语句使用方法
2007/09/21 Javascript
javascript之典型高阶函数应用介绍二
2013/01/10 Javascript
JavaScript 函数replace深入了解
2013/03/14 Javascript
jquery prop的使用介绍及与attr的区别
2013/12/19 Javascript
javascript获取checkbox复选框获取选中的选项
2014/08/12 Javascript
JavaScript仿淘宝页面图片滚动加载及刷新回顶部的方法解析
2016/05/24 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
JavaScript实现横线提示输入验证码随输入验证码输入消失的方法
2016/09/24 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
2016/12/16 Javascript
安装Python的web.py框架并从hello world开始编程
2015/04/25 Python
谈谈如何手动释放Python的内存
2016/12/17 Python
详解使用pymysql在python中对mysql的增删改查操作(综合)
2017/01/18 Python
Python书单 不将就
2017/07/11 Python
Python+tkinter使用80行代码实现一个计算器实例
2018/01/16 Python
解决Pandas的DataFrame输出截断和省略的问题
2019/02/08 Python
在Python函数中输入任意数量参数的实例
2019/07/16 Python
python如何将两个txt文件内容合并
2019/10/18 Python
Django1.11自带分页器paginator的使用方法
2019/10/31 Python
python基于TCP实现的文件下载器功能案例
2019/12/10 Python
在python里使用await关键字来等另外一个协程的实例
2020/05/04 Python
plt.figure()参数使用详解及运行演示
2021/01/08 Python
如何用Python编写一个电子考勤系统
2021/02/08 Python
canvas使用注意点总结
2013/07/19 HTML / CSS
小学五年级学生评语
2014/04/22 职场文书
信用卡逾期证明示例
2014/09/13 职场文书
小学思品教学反思
2016/02/20 职场文书
八年级作文之我的母亲
2019/12/10 职场文书