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 call和apply方法
Nov 24 Javascript
jQuery textarea的长度进行验证
May 06 Javascript
JavaScript动态调整TextArea高度的代码
Dec 28 Javascript
JavaScript中链式调用之研习
Apr 07 Javascript
jquery(live)中File input的change方法只起一次作用的解决办法
Oct 21 Javascript
javascript向flash swf文件传递参数值注意细节
Dec 11 Javascript
javasciprt下jquery函数$.post执行无响应的解决方法
Mar 13 Javascript
jquery和js实现对div的隐藏和显示方法
Sep 26 Javascript
jQuery实现切换字体大小的方法
Mar 10 Javascript
Javascript中的作用域和上下文深入理解
Jul 03 Javascript
AngularJS 避繁就简的路由
Jul 01 Javascript
vue远程加载sfc组件思路详解
Dec 25 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自动给文章加关键词链接的函数代码
2012/11/29 PHP
zf框架的Filter过滤器使用示例
2014/03/13 PHP
PHP实现HTML生成PDF文件的方法
2014/11/07 PHP
php+ajax实时刷新简单实例
2015/02/25 PHP
CI框架的安全性分析
2016/05/18 PHP
javascript中的location用法简单介绍
2007/03/07 Javascript
JQuery 1.6发布 性能提升,同时包含大量破坏性变更
2011/05/10 Javascript
Eval and new funciton not the same thing
2012/12/27 Javascript
hover的用法及live的用法介绍(鼠标悬停效果)
2013/03/29 Javascript
JS中获取数据库中的值的方法
2013/07/14 Javascript
JavaScript中setAttribute用法介绍
2013/07/20 Javascript
比较不错的JS/JQuery显示或隐藏文本的方法
2014/02/13 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
js加密解密字符串可自定义密码因子
2014/05/13 Javascript
再谈javascript原型继承
2014/11/10 Javascript
jQuery属性选择器用法示例
2016/09/09 Javascript
jQuery内容筛选选择器实例代码
2017/02/06 Javascript
Angular 作用域scope的具体使用
2017/12/11 Javascript
python处理html转义字符的方法详解
2016/07/01 Python
详解python 拆包可迭代数据如tuple, list
2017/12/29 Python
Django组件之cookie与session的使用方法
2019/01/10 Python
python3.6环境安装+pip环境配置教程图文详解
2019/06/20 Python
使用python写的opencv实时监测和解析二维码和条形码
2019/08/14 Python
Python random模块制作简易的四位数验证码
2020/02/01 Python
python实现简单井字棋游戏
2020/03/04 Python
Marlies Dekkers内衣美国官方网上商店:高端内衣品牌
2018/11/12 全球购物
美国爆米花工厂:The Popcorn Factory
2019/09/14 全球购物
英国领先的在线高尔夫商店:Gamola Golf
2019/11/16 全球购物
英国马莎百货印度官网:Marks & Spencer印度
2020/10/08 全球购物
学生保证书范文
2014/04/28 职场文书
县政府班子个人对照检查材料
2014/10/05 职场文书
幸福家庭事迹材料
2014/12/20 职场文书
内乡县衙导游词
2015/02/05 职场文书
Ajax请求超时与网络异常处理图文详解
2021/05/23 Javascript
四十九个javascript小知识实用技巧
2021/11/20 Javascript
从原生JavaScript到React深入理解
2022/07/23 Javascript