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的IE和Firefox兼容性汇编(zz)
Feb 02 Javascript
js和as的稳定传值问题解决
Jul 14 Javascript
JavaScript动态插入script的基本思路及实现函数
Nov 11 Javascript
jquery中EasyUI实现同步树
Mar 01 Javascript
JavaScript基于DOM操作实现简单的数学运算功能示例
Jan 16 Javascript
原生js仿浏览器滚动条效果
Mar 02 Javascript
完美解决手机浏览器顶部下拉出现网页源或刷新的问题
Nov 30 Javascript
JS实现不用中间变量temp 实现两个变量值得交换方法
Feb 04 Javascript
解决vue处理axios post请求传参的问题
Mar 05 Javascript
JS实现的3des+base64加密解密算法完整示例
May 18 Javascript
js+SVG实现动态时钟效果
Jul 14 Javascript
JavaScript数组去重的几种方法
Apr 07 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即CodeIgniter框架在Nginx下的重写规则
2013/06/03 PHP
PHP实现基于文本的摩斯电码生成器
2016/01/11 PHP
解决thinkphp5未定义变量会抛出异常,页面错误,请稍后再试的问题
2019/10/16 PHP
jQuery+css实现图片滚动效果(附源码)
2013/03/18 Javascript
jQuery层次选择器选择元素使用介绍
2013/04/18 Javascript
使用jQuery UI的tooltip函数修饰title属性的气泡悬浮框
2013/06/24 Javascript
使用jquery局部刷新(jquery.load)从数据库取出数据
2014/01/22 Javascript
详解jquery中$.ajax方法提交表单
2014/11/03 Javascript
javascript计时器详解
2015/02/28 Javascript
JQuery替换DOM节点的方法
2015/06/11 Javascript
JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
2015/11/24 Javascript
同步文本框内容JS代码实现
2016/08/04 Javascript
js style.display=block显示布局错乱问题的解决方法
2016/09/21 Javascript
AngularJS实现的简单拖拽功能示例
2018/01/02 Javascript
使用JS代码实现俄罗斯方块游戏
2018/08/03 Javascript
bootstrap里bootstrap动态加载下拉框的实例讲解
2018/08/10 Javascript
nuxt中使用路由守卫的方法步骤
2019/01/27 Javascript
vue cli 3.x 项目部署到 github pages的方法
2019/04/17 Javascript
axios如何利用promise无痛刷新token的实现方法
2019/08/27 Javascript
vscode中eslint插件的配置(prettier配置无效)
2019/09/10 Javascript
使用python绘制3维正态分布图的方法
2018/12/29 Python
Python批量修改图片分辨率的实例代码
2019/07/04 Python
python retrying模块的使用方法详解
2019/09/25 Python
Keras 切换后端方式(Theano和TensorFlow)
2020/06/19 Python
Original Penguin美国官网:布拉德皮特、强尼德普喜爱的服装品牌
2016/10/25 全球购物
Snapfish英国:在线照片打印和个性化照片礼品
2017/01/13 全球购物
绘画设计学生的个人自我评价
2013/09/20 职场文书
办理信用卡工作证明
2014/01/11 职场文书
简单租房协议书
2014/04/09 职场文书
法院反腐倡廉心得体会
2014/09/09 职场文书
求职自我评价范文100字
2014/09/23 职场文书
2014年体育教师工作总结
2014/12/03 职场文书
公司文体活动总结
2015/05/07 职场文书
Redis高并发防止秒杀超卖实战源码解决方案
2021/11/01 Redis
Python可视化学习之seaborn绘制矩阵图详解
2022/02/24 Python
十大最强奥特曼武器:怪兽战斗仪在榜,第五奥特之父只使用过一次
2022/03/18 日漫