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实现div的显示和隐藏的小例子
Jun 25 Javascript
解决json日期格式问题的3种方法
Feb 02 Javascript
Js与下拉列表处理问题解决
Feb 13 Javascript
jQuery使用slideUp方法实现控制元素缓慢收起
Mar 27 Javascript
JavaScript、jQuery与Ajax的关系
Jan 24 Javascript
Javascript数组Array基础介绍
Mar 13 Javascript
jQuery实现字体颜色渐变效果的方法
Mar 29 jQuery
javascript连接mysql与php通过odbc连接任意数据库的实例
Dec 27 Javascript
JS数组实现分类统计实例代码
Sep 30 Javascript
深入理解js A*寻路算法原理与具体实现过程
Dec 13 Javascript
微信小程序实现滑动翻页效果(完整代码)
Dec 06 Javascript
五句话帮你轻松搞定js原型链
Dec 09 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自定义hash函数实例
2015/05/05 PHP
PHP内核学习教程之php opcode内核实现
2016/01/27 PHP
php rsa 加密,解密,签名,验签详解
2016/12/06 PHP
HR vs CL BO3 第一场 2.13
2021/03/10 DOTA
js 省地市级联选择
2010/02/07 Javascript
javascript使用eval或者new Function进行语法检查
2010/10/16 Javascript
js获取某月的最后一天日期的简单实例
2013/06/22 Javascript
JS实现根据出生年月计算年龄
2014/01/10 Javascript
扩展jQuery对象时如何扩展成员变量具体怎么实现
2014/04/25 Javascript
javascript和jquery实现设置和移除文本框默认值效果代码
2015/01/13 Javascript
JS实现图片放大镜效果的方法
2015/02/27 Javascript
thinkphp实现无限分类(使用递归)
2015/12/19 Javascript
AngularJS 实现弹性盒子布局的方法
2016/08/30 Javascript
JavaScript中arguments和this对象用法分析
2018/08/08 Javascript
vueJs实现DOM加载完之后自动下拉到底部的实例代码
2018/08/31 Javascript
ios中视频的最后一桢问题解决
2019/05/14 Javascript
layui监听单元格编辑前后交互的例子
2019/09/16 Javascript
webpack 动态批量加载文件的实现方法
2020/03/19 Javascript
JS实现可控制的进度条
2020/03/25 Javascript
vscode中Vue别名路径提示的实现
2020/07/31 Javascript
Python利用公共键如何对字典列表进行排序详解
2018/05/19 Python
wxpython实现按钮切换界面的方法
2019/11/19 Python
python实现简易淘宝购物
2019/11/22 Python
Python中 Global和Nonlocal的用法详解
2020/01/20 Python
Python爬取阿拉丁统计信息过程图解
2020/05/12 Python
Python检测端口IP字符串是否合法
2020/06/05 Python
html2canvas生成清晰的图片实现打印的示例代码
2019/09/30 HTML / CSS
大三自我鉴定范文
2013/10/05 职场文书
管理科学大学生求职信
2013/11/13 职场文书
美德好少年主要事迹
2014/01/29 职场文书
幼儿园老师寄语
2014/04/03 职场文书
土建工程师岗位职责
2014/06/10 职场文书
教师批评与自我批评(群众路线)
2014/10/15 职场文书
追悼词范文大全
2015/06/23 职场文书
MySQL空间数据存储及函数
2021/09/25 MySQL
Nginx 安装SSL证书完成HTTPS部署
2022/04/28 Servers