[Effective JavaScript 笔记]第51条:在类数组对象上复用通用的数组方法
前面有几条都讲过关于Array.prototype的标准方法。这些标准方法被设计成其他对象可复用的方法,即使这些对象并没有继承Array。
arguments对象
在22条中提到的函数arguments对象。它是一个类数组对象,并不是一个标准的数组,所以无法使用数组原型中的方法,因此无法使用arguments.forEach这样的形式来遍历每一个参数。这里我们必须使用call方法来对使用forEach方法。
function highlight(){
[].forEach.call(arguments,function(widget){
widget.setBackground('yellow');
});
}
forEach是一个函数对象,所以它继承了Function.prototype对象中的call方法。这里就可以使用一个指定的对象作为函数内部this的绑定对象来调用它,并紧随任意数量的参数。
## NodeList对象
在Web平台,DOM的NodeList类是另一个类数组对象。类似的document.getElementsByTagName会返回一个NodeList类数组对象。这个对象也没有继承自Array.prototype.
类数组对象
怎样构建一个类数组对象?
具有一个范围在0到2^32-1的整形length属性
length属性大于该对象的最大索引。索引是一个范围在0到2^32-1的整数,它的字符串表示是该对象中的一个key
实现上面这两点,就可以使一个对象与Array.prototype中任一方法兼容。
一个简单的对象字面量也可以用来创建一个类数组对象。
var arrayLike={0:'a',1:'b',2:'c',length:3};
var res=Array.prototype.map.call(arrayLike,function(s){
return s.toUpperCase();
});
res;//['A','B','C']
字符串
也是可以表现为数组,因为它们是可索引,并且其长度也可以通过length属性获取。
因此,Array.protoype中的方法操作字符串时并不会修改原始字符串。
var res=Array.prototype.map.call('abc',function(s){return s.toUpperCase();});
res;//['A','B','C']
模拟数组
模拟数组的所有行为,归功于数组行为的两方面:
将length属性值设为小于n的值会自动地删除索引值大于或等于n的所有属性
增加一个索引值为n(大于或等于length属性值)的属性会自动地设置length属性为n+1
其中第2条规则不好实现,因为需要监控索引属性的增加以自动地更新length属性。
对于Array.prototype中的方法,这两条都不是必须的,因为在增加或删除索引属性的时候它们都会强制地更新length属性。
Array方法中只有一个不是通用的,即数组连接方法concat。该方法可以由任意的类数组接收者调用,但它会检查其参数[[Class]]属性。如果参数是一个真实的数组,那么concat会将该数组的内容连接起来作为结果;否则,参数将以一个单一的元素来连接。
例如,不能简单地连接一个以arguments对象作为内容的数组。
function namesColumn(){
return ['Names'].concat(arguments);
}
namesColumn('张三','李四','王五');//["Names", Arguments[3]0: "张三"1: "李四"2: "王五"callee: namesColumn()length: 3Symbol(Symbol.iterator): values()__proto__: Object]
使concat方法将一个类数组对象视为真实数组,需要把类数组转换为真正的数组。使用slice对类数组对象进行转换。
function namesColumn(){
return ['Names'].concat([].slice.call(arguments));
}
namesColumn('张三','李四','王五');//["Names", "张三", "李四", "王五"]
提示
对于类数组对象,通过提取方法对象并使用其call方法来复用通用的Array方法
任意一个具有索引属性和恰当length属性的对象都可以使用通用的Array方法
[Effective JavaScript 笔记]第51条:在类数组对象上复用通用的数组方法的更多相关文章
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记]第40条:避免继承标准类
ECMAScript标准库里配备了许多重要的类,如Array,function,以及Date等.扩展这些类生成子类可以方便完成很多工作,但它们的定义具有很多特殊的行为,所以很难写出行为正确的类. Ar ...
- [Effective JavaScript 笔记]第58条:区分数组对象和类数组对象
示例 设想有两个不同类的API.第一个是位向量:有序的位集合 var bits=new BitVector(); bits.enable(4); bits.enable([1,3,8,17]); bi ...
- [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑
构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...
- [Effective JavaScript 笔记]第66条:使用计数器来执行并行操作
第63条建议使用工具函数downloadAllAsync接收一个URL数组并下载所有文件,结果返回一个存储了文件内容的数组,每个URL对应一个字符串.downloadAllAsync并不只有清理嵌套回 ...
- [Effective JavaScript 笔记]第22条:使用arguments创建可变参数的函数
第21条讲述使用可变参数的函数average.该函数可处理任意数量的参数并返回这些参数的平均值. 如何创建可变参数的函数 1.实现固定元数的函数 书上的版本 function averageOfArr ...
随机推荐
- unity3d 扩展NGUI Tweener —— TweenFillAmount
好久没写博客了,上一篇是在今年上班之前写的 从年初到现在一篇没写过,每天都在加班,实在太忙了 上班半年多了,学到不少东西 今天分享一下刚写的小功能 TweenFillAmount 用过NGUI Twn ...
- css清楚浮动的几种常用方法
请先看博客:http://www.jb51.net/css/173023.html
- WCF入门(8)
前言 昨天买的usb无线路由到了,笔记本又可以愉快的上网了. 下午去办市民卡,被告知说“本人医保现在停保,要等继续缴才行”,白公交坐了那么远的路. 需要视频的进群,378190436. 第八集 Dif ...
- CSS3——3D效果
1.效果1 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" c ...
- eclipse快捷键的使用及概述
<eclipse快捷键的使用及概述> <Eclipse概述> Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服 ...
- zoj1665 dij变形
既然输入的是损坏率,那1-x就是剩余的.最后只要剩余的最大. #include<stdio.h> #include<string.h> #define Max 99999999 ...
- ES6的模块、构建工具及应用的发布
作者:寸志链接:https://zhuanlan.zhihu.com/p/19569085来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 总的说来就是按照将来的标准书写 ...
- 【CodeForces 297C】Splitting the Uniqueness
题意 序列s有n个数,每个数都是不同的,把它每个数分成两个数,组成两个序列a和b,使ab序列各自去掉个数后各自的其它数字都不同. 如果存在一个划分,就输出YES,并且输出两个序列,否则输出NO. 分析 ...
- 一个项目中哪些文件是要上传到 git上的,哪些是不必要的
- RegexBuddy正则表达式工具
RegexBuddy非常的好用,而且还能生成.net的代码. 我们在使用正则匹配时,毕竟.net提供的方法中,对于多行匹配就不能用单纯的正则去实现,而我们需要把它转换成相应的类库方法进行实现. 那么R ...