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 相关文章推荐
使用ajaxfileupload.js实现ajax上传文件php版
Jun 26 Javascript
jQuery移除tr无效的解决方法(tr是动态添加)
Sep 22 Javascript
JS 清除字符串数组中,重复元素的实现方法
May 24 Javascript
Bootstrap Table服务器分页与在线编辑应用总结
Aug 08 Javascript
Vue.js双向绑定实现原理详解
Dec 22 Javascript
求js数组的最大值和最小值的四种方法
Mar 03 Javascript
js中toString()和String()区别详解
Mar 23 Javascript
Laravel admin实现消息提醒、播放音频功能
Jul 10 Javascript
微信小程序实现吸顶特效
Jan 08 Javascript
ES6中Promise的使用方法实例总结
Feb 18 Javascript
vant 自定义 van-dropdown-item的用法
Aug 05 Javascript
一起深入理解js中的事件对象
Feb 06 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
咖啡因含量是由谁决定的?低因咖啡怎么来?低因咖啡适合什么人喝
2021/03/06 新手入门
PHP的AES加密算法完整实例
2016/07/20 PHP
详解Yii2.0使用AR联表查询实例
2017/06/16 PHP
CMSPRESS 10行代码搞定 PHP无限级分类2
2018/03/30 PHP
Laravel实现批量更新多条数据
2020/04/06 PHP
javascript比较文档位置
2008/04/08 Javascript
JS 操作符整理[推荐收藏]
2011/11/15 Javascript
Jquery 实现table样式的设定
2015/01/28 Javascript
Javascript核心读书有感之类型、值和变量
2015/02/11 Javascript
jquery+json实现数据二级联动的方法
2015/11/28 Javascript
jquery捕捉回车键及获取checkbox值与异步请求的方法
2015/12/24 Javascript
实例详解jQuery表单验证插件validate
2016/01/18 Javascript
jQuery拖拽排序插件制作拖拽排序效果(附源码下载)
2016/02/23 Javascript
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
2016/02/23 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
获取JS中网页各种高宽与位置的方法总结
2016/07/27 Javascript
React组件内事件传参实现tab切换的示例代码
2018/07/04 Javascript
javascript实现弹幕墙效果
2019/11/28 Javascript
JavaScript常用进制转换及位运算实例解析
2020/10/14 Javascript
python网络编程学习笔记(六):Web客户端访问
2014/06/09 Python
python调用java的jar包方法
2018/12/15 Python
超级实用的8个Python列表技巧
2020/08/24 Python
详解python with 上下文管理器
2020/09/02 Python
分布式全文检索引擎ElasticSearch原理及使用实例
2020/11/14 Python
css3的focus-within选择器的使用
2020/05/11 HTML / CSS
HTML5 Canvas中绘制椭圆的4种方法
2015/04/24 HTML / CSS
英国最大的奢侈品零售网络商城:Flannels
2016/09/16 全球购物
美国滑雪板和装备购物网站:Skis.com
2018/12/20 全球购物
Onzie官网:美国时尚瑜伽品牌
2019/08/21 全球购物
学生打架检讨书1000字
2014/01/16 职场文书
超市商业计划书
2014/05/04 职场文书
分公司总经理岗位职责
2014/08/03 职场文书
试用期员工工作自我评价
2014/09/10 职场文书
python tqdm用法及实例详解
2021/06/16 Python
openstack中的rpc远程调用的方法
2021/07/09 Python
微软Win11 全新照片应用面向 Dev预览版推出 新版本上手体验图集
2022/09/23 数码科技