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 相关文章推荐
extjs grid取到数据而不显示的解决
Dec 29 Javascript
jquery获取下拉列表的值为null的解决方法
Mar 18 Javascript
js中一个函数获取另一个函数返回值问题探讨
Nov 21 Javascript
用Javascript获取页面元素的具体位置
Dec 09 Javascript
图文详解Heap Sort堆排序算法及JavaScript的代码实现
May 04 Javascript
一道优雅面试题分析js中fn()和return fn()的区别
Jul 05 Javascript
Angular 路由route实例代码
Jul 12 Javascript
前端把html表格生成为excel表格的实例
Sep 19 Javascript
小程序开发基础之view视图容器
Aug 21 Javascript
浅谈vue后台管理系统权限控制思考与实践
Dec 19 Javascript
Vue实现数据请求拦截
Oct 23 Javascript
微信小程序对图片进行canvas压缩的方法示例详解
Nov 12 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获得当前的脚本网址
2007/12/10 PHP
教你在PHPStorm中配置Xdebug
2015/07/27 PHP
php实现多城市切换特效
2015/08/09 PHP
php实现多站点共用session实现单点登录的方法详解
2019/09/18 PHP
laravel 实现用户登录注销并限制功能
2019/10/24 PHP
Laravel框架数据库迁移操作实例详解
2020/04/06 PHP
php慢查询日志和错误日志使用详解
2021/02/27 PHP
Jquery 获取表单text,areatext,radio,checkbox,select值的代码
2009/11/12 Javascript
JS防止用户多次提交的简单代码
2013/08/01 Javascript
JQuery事件e参数的方法preventDefault()取消默认行为
2013/09/26 Javascript
JS实现左右拖动改变内容显示区域大小的方法
2015/10/13 Javascript
js实现iframe框架取值的方法(兼容IE,firefox,chrome等)
2015/11/26 Javascript
浅谈Node.js:fs文件系统模块
2016/12/08 Javascript
JS实现Ajax的方法分析
2016/12/20 Javascript
关于AngularJs数据的本地存储详解
2017/01/20 Javascript
js实现九宫格的随机颜色跳转
2017/02/19 Javascript
Vue路由钩子之afterEach beforeEach的区别详解
2018/07/15 Javascript
Vue 莹石摄像头直播视频实例代码
2018/08/31 Javascript
Vue 动态添加路由及生成菜单的方法示例
2019/06/20 Javascript
python图像处理之反色实现方法
2015/05/30 Python
Python基于DES算法加密解密实例
2015/06/03 Python
Python实现线程池代码分享
2015/06/21 Python
Python实现快速排序算法及去重的快速排序的简单示例
2016/06/26 Python
django正续或者倒序查库实例
2020/05/19 Python
python 瀑布线指标编写实例
2020/06/03 Python
光电信息专业应届生求职信
2013/10/07 职场文书
木工主管岗位职责
2013/12/08 职场文书
学生宿舍管理制度
2014/01/30 职场文书
模范家庭事迹材料
2014/02/10 职场文书
弘扬雷锋精神活动演讲稿
2014/03/04 职场文书
经贸专业毕业生求职信
2014/03/23 职场文书
2014年学生党支部工作总结
2014/12/20 职场文书
本溪水洞导游词
2015/02/11 职场文书
2015年客房服务员工作总结
2015/05/15 职场文书
Python标准库pathlib操作目录和文件
2021/11/20 Python
Java存储没有重复元素的数组
2022/04/29 Java/Android