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 相关文章推荐
jquery随意添加移除html的实现代码
Jun 21 Javascript
Javascript核心读书有感之词法结构
Feb 01 Javascript
JS中script标签defer和async属性的区别详解
Aug 12 Javascript
真正好用的js验证上传文件大小的简单方法
Oct 27 Javascript
jQuery EasyUI 选项卡面板tabs的使用实例讲解
Dec 25 jQuery
JS实现为动态创建的元素添加事件操作示例
Mar 17 Javascript
vue中的数据绑定原理的实现
Jul 02 Javascript
如何将HTML字符转换为DOM节点并动态添加到文档中详解
Aug 19 Javascript
详解ES6系列之私有变量的实现
Nov 21 Javascript
详解js location.href和window.open的几种用法和区别
Dec 02 Javascript
vue 基于abstract 路由模式 实现页面内嵌的示例代码
Dec 14 Vue.js
vue实现水波涟漪效果的点击反馈指令
May 31 Vue.js
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与已存在的Java应用程序集成
2006/10/09 PHP
ADODB结合SMARTY使用~超级强
2006/11/25 PHP
利用discuz自带通行证整合dedecms的方法以及文件下载
2007/03/06 PHP
php调整服务器时间的方法
2015/04/03 PHP
Thinkphp5+uploadify实现的文件上传功能示例
2018/05/26 PHP
Yii框架操作cookie与session的方法实例详解
2019/09/04 PHP
PHP number_format函数原理及实例解析
2020/07/14 PHP
javascript 循环调用示例介绍
2013/11/20 Javascript
jQuery中slideUp()方法用法分析
2014/12/24 Javascript
jQuery实现根据滚动条位置加载相应内容功能
2016/07/18 Javascript
jQuery轮播图效果精简版完整示例
2016/09/04 Javascript
angular ng-repeat数组中的数组实例
2017/02/18 Javascript
关于Vue Webpack2单元测试示例详解
2017/08/14 Javascript
React Native实现地址挑选器功能
2017/10/24 Javascript
vue实现中部导航栏布局功能
2019/07/30 Javascript
JavaScript使用表单元素验证表单的示例代码
2019/08/20 Javascript
在layui.use 中自定义 function 的正确方法
2019/09/16 Javascript
Javascript模拟实现new原理解析
2020/03/03 Javascript
vue3使用vue-count-to组件的实现
2020/12/25 Vue.js
[54:09]RNG vs Liquid 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
Python3.2模拟实现webqq登录
2016/02/15 Python
对numpy Array [: ,] 的取值方法详解
2018/07/02 Python
对numpy中数组转置的求解以及向量内积计算方法
2018/10/31 Python
python3 使用traceback定位异常实例
2020/03/09 Python
python 第三方库paramiko的常用方式
2021/02/20 Python
美国鞋类购物网站:Shiekh Shoes
2016/08/21 全球购物
加拿大消费电子和手机购物网站:The Source
2017/01/28 全球购物
法国女性内衣购物网站:Glamuse
2019/05/13 全球购物
俄罗斯品牌服装和鞋子的在线商店:KUPIVIP
2019/10/27 全球购物
个人四风问题对照检查材料
2014/09/26 职场文书
家长高考寄语
2015/02/27 职场文书
2015大学迎新标语
2015/07/16 职场文书
优秀党员主要事迹材料
2015/11/04 职场文书
奇妙的 CSS shapes(CSS图形)
2021/04/05 HTML / CSS
Python机器学习之基础概述
2021/05/19 Python
python 多态 协议 鸭子类型详解
2021/11/27 Python