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 相关文章推荐
Javascript中Eval函数的使用说明
Oct 11 Javascript
Dojo 学习要点
Sep 03 Javascript
IE下JS读取xml文件示例代码
Aug 05 Javascript
jquery $(this).attr $(this).val方法使用介绍
Oct 08 Javascript
浅析Cookie中的Path与domain
Dec 18 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
Sep 22 Javascript
jQuery使用hide方法隐藏页面上指定元素的方法
Mar 30 Javascript
Jquery操作cookie记住用户名
Mar 29 Javascript
基于angularjs实现图片放大镜效果
Aug 31 Javascript
Angular组件化管理实现方法分析
Mar 17 Javascript
javascript简写常用的12个技巧(可以大大减少你的js代码量)
Mar 28 Javascript
vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)
Oct 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
php自定义的格式化时间示例代码
2013/12/05 PHP
php+ajax登录跳转登录实现思路
2016/07/31 PHP
php插入含有特殊符号数据的处理方法
2016/11/24 PHP
php+jQuery ajax实现的实时刷新显示数据功能示例
2019/09/12 PHP
用于判断用户注册时,密码强度的JS代码
2009/01/01 Javascript
javascript下对于事件、事件流、事件触发的顺序随便说说
2010/07/17 Javascript
jQuery boxy弹出层插件中文演示及使用讲解
2011/02/24 Javascript
AngularJs Dependency Injection(DI,依赖注入)
2016/09/02 Javascript
jQuery内容过滤选择器用法示例
2016/09/09 Javascript
Bootstrap CDN和本地化环境搭建
2016/10/26 Javascript
利用node.js+mongodb如何搭建一个简单登录注册的功能详解
2017/07/30 Javascript
详解vue2 $watch要注意的问题
2017/09/08 Javascript
解决VUEX兼容IE上的报错问题
2018/03/01 Javascript
React native ListView 增加顶部下拉刷新和底下点击刷新示例
2018/04/27 Javascript
vue中el-upload上传图片到七牛的示例代码
2018/10/19 Javascript
iview在vue-cli3如何按需加载的方法
2018/10/31 Javascript
[00:58]PWL开团时刻DAY5——十人开雾0换5
2020/11/04 DOTA
python分割和拼接字符串
2013/11/01 Python
Python(Tornado)模拟登录小米抢手机
2013/11/12 Python
Python多进程multiprocessing用法实例分析
2017/08/18 Python
Python读取txt文件数据的方法(用于接口自动化参数化数据)
2018/06/27 Python
python flask解析json数据不完整的解决方法
2019/05/26 Python
简单了解Python matplotlib线的属性
2019/06/29 Python
linux环境中没有网络怎么下载python
2019/07/07 Python
python 中Arduino串口传输数据到电脑并保存至excel表格
2019/10/14 Python
python使用yield压平嵌套字典的超简单方法
2019/11/02 Python
如何在 Django 模板中输出 "{{"
2020/01/24 Python
Tensorflow限制CPU个数实例
2020/02/06 Python
python获取本周、上周、本月、上月及本季的时间代码实例
2020/09/08 Python
结合CSS3的布局新特征谈谈常见布局方法
2016/01/22 HTML / CSS
Hotels.com中国区:好订网
2016/08/18 全球购物
澳大利高级泳装品牌:Bondi Born
2018/05/23 全球购物
《社戏》教学反思
2014/04/15 职场文书
幼儿园老师工作总结2015
2015/05/22 职场文书
横空出世观后感
2015/06/09 职场文书
2016年感恩教师节活动总结
2016/04/01 职场文书