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 相关文章推荐
Prototype使用指南之array.js
Jan 10 Javascript
JScript中的undefined和"undefined"的区别
Mar 08 Javascript
JavaScript 全面解析各种浏览器网页中的JS 执行顺序
Feb 17 Javascript
jquery实现可拖拽弹出层特效
Jan 04 Javascript
jQuery中parents()方法用法实例
Jan 07 Javascript
Jquery搜索父元素操作方法
Feb 10 Javascript
RequireJS入门一之实现第一个例子
Sep 30 Javascript
解析Node.js异常处理中domain模块的使用方法
Feb 16 Javascript
基于jquery插件编写countdown计时器
Jun 12 Javascript
获取input标签的所有属性的方法
Jun 28 Javascript
前端实现文件的断点续传(前端文件提交+后端PHP文件接收)
Nov 04 Javascript
AngularJS Toaster使用详解
Feb 24 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
smarty实例教程
2006/11/19 PHP
PHP使用mysql_fetch_object从查询结果中获取对象集的方法
2015/03/18 PHP
PHP数组的定义、初始化和数组元素的显示实现代码
2016/11/05 PHP
showModelessDialog()使用详解
2006/09/07 Javascript
图片在浏览器中底部对齐 解决方法之一
2011/11/30 Javascript
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
2013/02/05 Javascript
Jquery实现地铁线路指示灯提示牌效果的方法
2015/03/02 Javascript
JQuery显示隐藏页面元素的方法总结
2015/04/16 Javascript
AngularJS基础学习笔记之表达式
2015/05/10 Javascript
Javascript实现div层渐隐效果的方法
2015/05/30 Javascript
举例详解AngularJS中ngShow和ngHide的使用方法
2015/06/19 Javascript
jquery实现TAB选项卡鼠标经过带延迟效果的方法
2015/07/27 Javascript
使用jQuery制作浮动工具栏的实例分享
2016/05/13 Javascript
jQuery过滤选择器经典应用
2016/08/18 Javascript
bootstrap datepicker限定可选时间范围实现方法
2016/09/28 Javascript
JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】
2019/02/22 Javascript
一篇文章介绍redux、react-redux、redux-saga总结
2019/05/23 Javascript
微信小程序 checkbox使用实例解析
2019/09/09 Javascript
python启动办公软件进程(word、excel、ppt、以及wps的et、wps、wpp)
2009/04/09 Python
使用python实现扫描端口示例
2014/03/29 Python
Python实现的旋转数组功能算法示例
2019/02/23 Python
Django框架自定义session处理操作示例
2019/05/27 Python
python变量命名的7条建议
2019/07/04 Python
python绘制多个子图的实例
2019/07/07 Python
在Django下测试与调试REST API的方法详解
2019/08/29 Python
Python 多线程C段扫描、检测 Ping扫描脚本的实现
2020/09/03 Python
美国时装品牌:Nautica(诺帝卡)
2016/08/28 全球购物
计算机专业大学生的自我评价
2013/11/14 职场文书
高三语文复习计划
2015/01/19 职场文书
新生入学欢迎词
2015/01/26 职场文书
员工年度工作总结2015
2015/05/18 职场文书
私人贷款担保书该怎么写呢?
2019/07/02 职场文书
教你快速开启Apache SkyWalking的自监控
2021/04/25 Servers
浅谈Go语言多态的实现与interface使用
2021/06/16 Golang
一次SQL如何查重及去重的实战记录
2022/03/13 MySQL
python绘制云雨图raincloud plot
2022/08/05 Python