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 相关文章推荐
实例讲解jQuery EasyUI tree中state属性慎用
Apr 01 Javascript
jquery ui sortable拖拽后保存位置
Apr 27 jQuery
AngularJS中controller控制器继承的使用方法
Nov 03 Javascript
浅谈Vue2.0中v-for迭代语法的变化(key、index)
Mar 06 Javascript
详解angular分页插件tm.pagination二次触发问题解决方案
Jul 20 Javascript
layui弹出层按钮提交iframe表单的方法
Aug 20 Javascript
Electron-vue脚手架改造vue项目的方法
Oct 22 Javascript
jQuery-ui插件sortable实现自由拖动排序
Dec 01 jQuery
Vue 报错TypeError: this.$set is not a function 的解决方法
Dec 17 Javascript
vue 详情跳转至列表页实现列表页缓存
Mar 27 Javascript
小程序分享模块超级详解(推荐)
Apr 10 Javascript
Vue实例的对象参数options的几个常用选项详解
Nov 08 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中copy on write写时复制机制介绍
2014/05/13 PHP
php中convert_uuencode()与convert_uuencode函数用法实例
2014/11/22 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
php文件操作相关类实例
2015/06/18 PHP
编写PHP脚本来实现WordPress中评论分页的功能
2015/12/10 PHP
PHP从二维数组得到N层分类树的实现代码
2016/10/11 PHP
php并发加锁示例
2016/10/17 PHP
PHP实现的各类hash算法长度及性能测试实例
2017/08/27 PHP
遍历jquery对象的代码分享
2011/11/02 Javascript
二叉树先序遍历的非递归算法具体实现
2014/01/09 Javascript
Javascript 构造函数详解
2014/10/22 Javascript
jQuery中append()方法用法实例
2014/12/25 Javascript
使用jquery制作弹出框效果
2015/04/03 Javascript
JS实现的仿QQ空间图片弹出效果代码
2016/02/23 Javascript
拖动时防止选中
2017/02/03 Javascript
Angularjs渲染的 using 指令的星级评分系统示例
2017/11/09 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
Bootstrap实现翻页效果
2017/11/27 Javascript
javascript 原型与原型链的理解及应用实例分析
2020/02/10 Javascript
element el-tree组件的动态加载、新增、更新节点的实现
2020/02/27 Javascript
Vue点击切换Class变化,实现Active当前样式操作
2020/07/17 Javascript
Python检测一个对象是否为字符串类的方法
2015/05/21 Python
python读取文件名称生成list的方法
2018/04/27 Python
python3实现的zip格式压缩文件夹操作示例
2019/08/17 Python
python中property属性的介绍及其应用详解
2019/08/29 Python
python的faker库用法
2019/11/28 Python
美国知名运动产品零售商:Foot Locker
2016/07/23 全球购物
美国百年历史早餐食品供应商:Wolferman’s
2017/01/18 全球购物
巴黎卡诗美国官方网站:始于1964年的头发头皮护理专家
2017/07/10 全球购物
最耐用行李箱,一箱永流传:Briggs & Riley(全球终身保修)
2017/12/07 全球购物
美国隐形眼镜网上商店:Lens.com
2019/09/03 全球购物
安全生产实施方案
2014/02/23 职场文书
请假条格式范文
2014/04/10 职场文书
个人委托函范文
2015/01/29 职场文书
淘宝文案策划岗位职责
2015/04/14 职场文书
2016大学生求职自荐信范文
2016/01/28 职场文书