JavaScript 里的类数组对象


Posted in Javascript onApril 08, 2015

很早以前我就知道可以把 arguments 转化为数组:[].slice.call(arguments),因为
arguments 是个类数组对象,所以才可以这么用。但是我一直不清楚什么叫做类数组对象( array-like objects)

今天看 Effective JavaScript 就有一节是专门讲这个的,感觉真是太拽了。

先看我写的一些示例代码:

a = "hello"

[].map.call(a, (e) -> e.toUpperCase()) # => [ 'H', 'E', 'L', 'L', 'O' ]

[].reduceRight.call(a, (acc, e) -> acc + e) # => 'olleh'

b = {1: "a", 2: "b", 4: "c", length: 6}

[].reduce.call(b, (acc, e) -> acc + e) # => 'abc'

前面那几个是操作字符串的,嗯,字符串也可以看成类数组对象。但是后面那个 b 对象居然
也是类数组对象。

看书上的解释:

So what exactly makes an object “array-like”? The basic contract of

an array object amounts to two simple rules.

It has an integer length property in the range 0...2^32 ? 1.

The length property is greater than the largest index of the object.

An index is an integer in the range 0...2^32 ? 2 whose string representation

is the key of a property of the object.

居然只有这两条简单的规则。

所以为什么 arguments, 字符串,和上面那个 b 对象可以看作类数组对象呢?

它们都有一个合法的 length 属性(0 到 2**32 - 1 之间的正整数)。
length 属性的值大于它们的最大索引(index)。
再举个例子:

b = {1: "a", 2: "b", 4: "c", length: 3}

[].reduce.call(b, (acc, e) -> acc + e) # => 'ab'

嗯,就不对了,成了'ab' 了,因为违反了规则2:length 属性是3,
最大索引值是4要比 length 属性大了。所以表现的不正常了。

太强大了,好像只是定义了一个接口,只要符合这个接口,就可以利用数组的所有方法。

其实不是可以利用所有方法,Array.prototype.concat
是不能用的,因为它是把两个数组连接起来,你不是数组肯定是没法用它的。

还有一个小问题是,字符串创建以后是不可变的(immutable),所以你怎么折腾它都是不可变的。

但是这本书根本就没有解释为什么是符合这两个条件就可以看成类数组对象,另外这本书的作者
是那个什么 ECMAScript 委员会的成员,所以基本还是可信的。至于为什么符合这两个条件就可以看成是类数组对象,我也不知道,谷歌搜了半天也没看到什么合理的解释。

以上所述就是本文的全部内容了,希望大家能够喜欢。

Javascript 相关文章推荐
在IE下:float属性会影响offsetTop的取值
Dec 22 Javascript
THREE.JS入门教程(3)着色器-下
Jan 24 Javascript
理解javascript中Map代替循环
Feb 26 Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
May 31 Javascript
canvas实现弧形可拖动进度条效果
May 11 Javascript
Vue.js devtool插件安装后无法使用的解决办法
Nov 27 Javascript
vue权限管理系统的实现代码
Jan 17 Javascript
基于node简单实现RSA加解密的方法步骤
Mar 21 Javascript
微信小程序开发注意指南和优化实践(小结)
Jun 21 Javascript
利用d3.js制作连线动画图与编辑器的方法实例
Sep 05 Javascript
Vue.js实现可编辑的表格
Dec 11 Javascript
js 实现验证码输入框示例详解
Sep 23 Javascript
cookie的secure属性详解
Apr 08 #Javascript
jQuery简单tab切换效果实现方法
Apr 08 #Javascript
JavaScript中的普通函数与构造函数比较
Apr 07 #Javascript
jQuery控制cookie过期时间的方法
Apr 07 #Javascript
JavaScript随机生成信用卡卡号的方法
Apr 07 #Javascript
JavaScript实现信用卡校验方法
Apr 07 #Javascript
jQuery控制网页打印指定区域的方法
Apr 07 #Javascript
You might like
PHP5中MVC结构学习
2006/10/09 PHP
PHP获取服务器端信息的方法
2014/11/28 PHP
对JavaScript的eval()中使用函数的进一步讨论
2008/07/26 Javascript
div+css+js实现无缝滚动类似marquee无缝滚动兼容firefox
2013/08/29 Javascript
在Iframe中获取父窗口中表单的值(示例代码)
2013/11/22 Javascript
jquery仿搜索自动联想功能代码
2014/05/23 Javascript
js中匿名函数的创建与调用方法分析
2014/12/19 Javascript
javascript检查浏览器是否已经启用XX功能
2015/07/10 Javascript
基于javascript制作经典传统的拼图游戏
2016/03/22 Javascript
深入理解jquery自定义动画animate()
2016/05/24 Javascript
BOM系列第一篇之定时器setTimeout和setInterval
2016/08/17 Javascript
Bootstrap CSS组件之按钮下拉菜单
2016/12/17 Javascript
Vue 中的受控与非受控组件的实现
2018/12/17 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧不动,右侧滑动)
2019/01/23 Javascript
Vue状态模式实现窗口停靠功能(灵动、自由, 管理后台Admin界面)
2020/03/06 Javascript
vue下拉刷新组件的开发及slot的使用详解
2020/12/23 Vue.js
python开发之list操作实例分析
2016/02/22 Python
python安装PIL模块时Unable to find vcvarsall.bat错误的解决方法
2016/09/19 Python
简单实现python进度条脚本
2017/12/18 Python
在python中实现将一张图片剪切成四份的方法
2018/12/05 Python
django-rest-swagger的优化使用方法
2019/08/29 Python
Python Gluon参数和模块命名操作教程
2019/12/18 Python
详解有关PyCharm安装库失败的问题的解决方法
2020/02/02 Python
python GUI库图形界面开发之PyQt5信号与槽基础使用方法与实例
2020/03/06 Python
python Yaml、Json、Dict之间的转化
2020/10/19 Python
HTML5自定义data-* data(obj)属性和jquery的data()方法的使用
2012/12/13 HTML / CSS
欧洲最大的滑雪假期供应商之一:Sunweb Holidays
2018/01/06 全球购物
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
璀璨的珍珠、密钉和个性化珠宝:Lily & Roo
2021/01/21 全球购物
员工安全承诺书
2014/05/22 职场文书
优秀的应届生自荐信
2014/05/23 职场文书
体检通知范文
2015/04/21 职场文书
毕业生捐书活动倡议书
2015/04/27 职场文书
雷锋观后感
2015/06/10 职场文书
《秋天的雨》教学反思
2016/02/19 职场文书
六年级作文之预言作文
2019/10/25 职场文书