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在页面底部加载的注意事项介绍
Jul 18 Javascript
简单的代码实现jquery定时器
Jan 03 Javascript
用console.table()调试javascript
Sep 04 Javascript
JavaScript中String.prototype用法实例
May 20 Javascript
详解JavaScript中数组的相关知识
Jul 29 Javascript
JS实现样式清新的横排下拉菜单效果
Oct 09 Javascript
Javascript缓存API
Jun 14 Javascript
vuejs在解析时出现闪烁的原因及防止闪烁的方法
Sep 19 Javascript
JS+CSS实现下拉刷新/上拉加载插件
Mar 31 Javascript
vuex的module模块用法示例
Nov 12 Javascript
JavaScript数据结构与算法之二叉树遍历算法详解【先序、中序、后序】
Feb 21 Javascript
如何使用JavaScript实现栈与队列
Jun 24 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
第十节 抽象方法和抽象类 [10]
2006/10/09 PHP
PHP错误机制知识汇总
2016/03/24 PHP
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
2016/12/14 PHP
PHP获取当前URL路径的处理方法(适用于多条件筛选列表)
2017/02/10 PHP
CSS和Javascript简单复习资料
2010/06/29 Javascript
jquery validate 自定义验证方法介绍 日期验证
2014/02/27 Javascript
轻松创建nodejs服务器(2):nodejs服务器的构成分析
2014/12/18 NodeJs
jQuery中:first-child选择器用法实例
2014/12/31 Javascript
AngularJS出现$http异步后台无法获取请求参数问题的解决方法
2016/11/03 Javascript
Bootstrap基本组件学习笔记之input输入框组(9)
2016/12/07 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
jQuery 判断元素整理汇总
2017/02/28 Javascript
如何使用angularJs
2017/05/08 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
Bootstrap组件之下拉菜单,多级菜单及按钮布局方法实例
2017/05/25 Javascript
webpack2.0配置postcss-loader的方法
2017/08/17 Javascript
Vue Element使用icon图标教程详解(第三方)
2018/02/07 Javascript
从零开始搭建一个react项目开发
2018/02/09 Javascript
javascript中的隐式调用
2018/02/10 Javascript
javascript 关于赋值、浅拷贝、深拷贝的个人理解
2019/11/01 Javascript
vue实现鼠标移过出现下拉二级菜单功能
2019/12/12 Javascript
Vue中el-form标签中的自定义el-select下拉框标签功能
2020/04/20 Javascript
[01:09:16]DOTA2-DPC中国联赛 正赛 SAG vs Dynasty BO3 第一场 1月25日
2021/03/11 DOTA
使用python加密自己的密码
2015/08/04 Python
离线安装Pyecharts的步骤以及依赖包流程
2020/04/23 Python
使用python PIL库实现简单验证码的去噪方法步骤
2019/05/10 Python
python实现的爬取电影下载链接功能示例
2019/08/26 Python
如何修复使用 Python ORM 工具 SQLAlchemy 时的常见陷阱
2019/11/19 Python
通过Python扫描代码关键字并进行预警的实现方法
2020/05/24 Python
keras实现图像预处理并生成一个generator的案例
2020/06/17 Python
python报错TypeError: ‘NoneType‘ object is not subscriptable的解决方法
2020/11/05 Python
党建示范点实施方案
2014/03/12 职场文书
施工安全生产承诺书
2014/05/23 职场文书
暖通工程师岗位职责
2014/06/12 职场文书
python读取mnist数据集方法案例详解
2021/09/04 Python
详解使用内网穿透工具Ngrok代理本地服务
2022/03/31 Servers