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 相关文章推荐
通过js动态操作table(新增,删除相关列信息)
May 23 Javascript
JavaScript对象和字串之间的转换实例探讨
Apr 21 Javascript
获取中文字符串的实际长度代码
Jun 05 Javascript
让人蛋疼的JavaScript语法特性
Sep 30 Javascript
jQuery圆形统计图开发实例
Jan 04 Javascript
JavaScript常用的弹出广告及背投广告实现方法
Feb 06 Javascript
Bootstrap每天必学之面板
Nov 30 Javascript
Bootstrap 附加导航(Affix)插件实例详解
Jun 01 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
Aug 03 Javascript
vue src动态加载请求获取图片的方法
Oct 17 Javascript
基于layui轮播图满屏是高度自适应的解决方法
Sep 16 Javascript
详解微信小程序工程化探索之webpack实战
Apr 20 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
PHP实现C#山寨ArrayList的方法
2015/07/16 PHP
在laravel框架中使用model层的方法
2019/10/08 PHP
Extjs gridpanel 出现横向滚动条问题的解决方法
2011/07/04 Javascript
js获取图片大小的函数代码
2011/09/20 Javascript
javascript full screen 全屏显示页面元素的方法
2013/09/27 Javascript
javascript中为某个元素指定事件的三种方式
2014/08/07 Javascript
简介JavaScript中POSITIVE_INFINITY值的使用
2015/06/05 Javascript
Node.js编写组件的三种实现方式
2016/02/25 Javascript
一起学写js Calender日历控件
2016/04/14 Javascript
浅析Node.js实现HTTP文件下载
2016/08/05 Javascript
knockoutjs模板实现树形结构列表
2017/07/31 Javascript
Vue中的Vux配置指南
2017/12/08 Javascript
Vue+jquery实现表格指定列的文字收缩的示例代码
2018/01/09 jQuery
vue文件树组件使用详解
2018/03/29 Javascript
js replace 全局替换的操作方法
2018/06/12 Javascript
详解如何用VUE写一个多用模态框组件模版
2018/09/27 Javascript
Javascript 实现 Excel 导入生成图表功能
2018/10/22 Javascript
js 计数排序的实现示例(升级版)
2020/01/12 Javascript
[01:18]DOTA2超级联赛专访hanci ForLove淘汰感言曝光
2013/06/04 DOTA
Python CSV模块使用实例
2015/04/09 Python
Python Paramiko模块的使用实际案例
2018/02/01 Python
python按时间排序目录下的文件实现方法
2018/10/17 Python
python中metaclass原理与用法详解
2019/06/25 Python
python射线法判断一个点在图形区域内外
2019/06/28 Python
Selenium 滚动页面至元素可见的方法
2020/03/18 Python
Python 操作 PostgreSQL 数据库示例【连接、增删改查等】
2020/04/21 Python
Python利用Faiss库实现ANN近邻搜索的方法详解
2020/08/03 Python
车辆安全检查制度
2014/01/12 职场文书
绿色城市实施方案
2014/03/19 职场文书
倡议书格式模板
2014/05/13 职场文书
交通事故和解协议书
2014/09/25 职场文书
2014年法院个人工作总结
2014/12/17 职场文书
硕士论文致谢范文
2015/05/14 职场文书
优秀班干部主要事迹材料
2015/11/04 职场文书
个人道歉信大全
2019/04/11 职场文书
Python如何让字典保持有序排列
2022/04/29 Python