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创建和存储cookie示例
Jan 07 Javascript
javascript间隔定时器(延时定时器)学习 间隔调用和延时调用
Jan 13 Javascript
jQuery实现径向动画菜单效果
Jul 17 Javascript
在AngularJS中使用jQuery的zTree插件的方法
Apr 21 Javascript
BootStrap 智能表单实战系列(五) 表单依赖插件处理
Jun 13 Javascript
JavaScript创建对象的七种方式全面总结
Aug 21 Javascript
jQuery easyui datagird编辑行删除行功能的实现代码
Sep 20 jQuery
vue中axios请求的封装实例代码
Mar 23 Javascript
element-ui中Table表格省市区合并单元格的方法实现
Aug 07 Javascript
微信小程序开发之转发分享功能
Oct 22 Javascript
JS事件循环机制event loop宏任务微任务原理解析
Aug 04 Javascript
Vue 3.0中jsx语法的使用
Nov 13 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-MySQL教程归纳总结
2008/06/07 PHP
Zend Framework教程之响应对象的封装Zend_Controller_Response实例详解
2016/03/07 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
PHP使用PDO创建MySQL数据库、表及插入多条数据操作示例
2019/05/30 PHP
[原创]来自ImageSee官方 JavaScript图片浏览器
2008/01/16 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
2014/01/10 Javascript
js实现iGoogleDivDrag模块拖动层拖动特效的方法
2015/03/04 Javascript
js实现温度计时间样式代码分享
2015/08/21 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
2016/01/27 Javascript
Angular2 PrimeNG分页模块学习
2017/01/14 Javascript
详解vue-cil和webpack中本地静态图片的路径问题解决方案
2017/09/27 Javascript
详解React+Koa实现服务端渲染(SSR)
2018/05/23 Javascript
element-ui中的select下拉列表设置默认值方法
2018/08/24 Javascript
基于element-ui组件手动实现单选和上传功能
2018/12/06 Javascript
微信小程序使用for循环动态渲染页面操作示例
2018/12/25 Javascript
微信小程序实现卡片层叠滑动效果
2019/06/21 Javascript
ES2020系列之空值合并运算符 '??'
2020/07/22 Javascript
wxPython定时器wx.Timer简单应用实例
2015/06/03 Python
Python实现的自定义多线程多进程类示例
2018/03/23 Python
Python/ArcPy遍历指定目录中的MDB文件方法
2018/10/27 Python
Python3获取电脑IP、主机名、Mac地址的方法示例
2019/04/11 Python
解决pycharm下os.system执行命令返回有中文乱码的问题
2019/07/07 Python
Python csv文件的读写操作实例详解
2019/11/19 Python
pytorch动态网络以及权重共享实例
2020/01/06 Python
tensorflow生成多个tfrecord文件实例
2020/02/17 Python
解决python -m pip install --upgrade pip 升级不成功问题
2020/03/05 Python
python 线程的五个状态
2020/09/22 Python
基于Django集成CAS实现流程详解
2020/11/28 Python
自动化专业本科毕业生求职信
2013/10/20 职场文书
个人贷款担保书
2014/04/01 职场文书
银行服务明星推荐材料
2014/05/29 职场文书
群众路线教育实践活动学习笔记内容
2014/11/06 职场文书
世界水日宣传活动总结
2015/02/09 职场文书
公司保洁员管理制度
2015/08/04 职场文书
导游词之青岛太清宫
2019/12/13 职场文书
解决SpringBoot跨域的三种方式
2021/06/26 Java/Android