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 循环调用示例介绍
Nov 20 Javascript
js对文章内容进行分页示例代码
Mar 05 Javascript
jQuery实现加入购物车飞入动画效果
Mar 14 Javascript
JavaScript检测弹出窗口是否已经关闭的方法
Mar 24 Javascript
jQuery选择器源码解读(一):Sizzle方法
Mar 31 Javascript
原生JavaScript实现瀑布流布局
Jun 28 Javascript
jQuery Validate表单验证插件的基本使用方法及功能拓展
Jan 04 Javascript
jQuery插件FusionCharts实现的3D帕累托图效果示例【附demo源码】
Mar 25 jQuery
详解vue嵌套路由-params传递参数
May 23 Javascript
浅谈vue路径优化之resolve
Oct 13 Javascript
vue实现导航栏效果(选中状态刷新不消失)
Dec 13 Javascript
小程序富文本提取图片可放大缩小
May 26 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扩展” 的解决方法
2007/04/16 PHP
PHP 获取远程文件内容的函数代码
2010/03/24 PHP
php中使用gd库实现下载网页中所有图片
2015/05/12 PHP
Django 标签筛选的实现代码(一对多、多对多)
2018/09/05 PHP
PHP中引用类型和值类型功能与用法示例
2019/02/26 PHP
为Yahoo! UI Extensions Grid增加内置的可编辑器
2007/03/10 Javascript
利用js获取服务器时间的两个简单方法
2010/01/08 Javascript
Jquery ajax传递复杂参数给WebService的实现代码
2011/08/08 Javascript
jQuery Tools tooltip使用说明
2012/07/14 Javascript
js几秒以后倒计时跳转示例
2013/12/26 Javascript
解决JS无法调用Controller问题的方法
2015/12/31 Javascript
jQuery图片轮播插件——前端开发必看
2016/05/31 Javascript
jQuery的ajax和遍历数组json实例代码
2016/08/01 Javascript
利用prop-types第三方库对组件的props中的变量进行类型检测
2017/05/02 Javascript
微信小程序swiper组件用法实例分析【附源码下载】
2017/12/07 Javascript
Angular实现模版驱动表单的自定义校验功能(密码确认为例)
2018/05/17 Javascript
BootStrap modal实现拖拽功能
2018/12/01 Javascript
使用vue2.6实现抖音【时间轮盘】屏保效果附源码
2019/04/24 Javascript
JSON是什么?有哪些优点?JSON和XML的区别?
2019/04/29 Javascript
微信小程序下拉框搜索功能的实现方法
2019/07/31 Javascript
Node.js在图片模板上生成二维码图片并附带底部文字说明实现详解
2019/08/07 Javascript
利用Python演示数型数据结构的教程
2015/04/03 Python
新手如何快速入门Python(菜鸟必看篇)
2017/06/10 Python
django将网络中的图片,保存成model中的ImageField的实例
2019/08/07 Python
Selenium Webdriver元素定位的八种常用方式(小结)
2021/01/13 Python
纯CSS3制作漂亮带动画效果的主机价格表
2015/04/25 HTML / CSS
用CSS3打造HTML5的Logo(实现代码)
2016/06/16 HTML / CSS
微软马来西亚官方网站:Microsoft马来西亚
2019/11/22 全球购物
住房公积金接收函
2014/01/09 职场文书
党的群众路线教育实践活动个人自我剖析材料
2014/10/07 职场文书
2014年技术工作总结范文
2014/11/20 职场文书
少年雷锋观后感
2015/06/10 职场文书
秋季运动会加油词
2015/07/18 职场文书
2015年教务主任工作总结
2015/07/22 职场文书
python 实现mysql自动增删分区的方法
2021/04/01 Python
一次SQL查询优化原理分析(900W+数据从17s到300ms)
2022/06/10 SQL Server