[Effective JavaScript 笔记]第24条:使用变量保存arguments对象
迭代器(iterator)是一个可以顺序存取数据集合的对象。其一个典型的API是next方法。该方法获得序列中的下一个值。
迭代器示例
题目:希望编写一个便利的函数,它可以接收任意数量的参数,并为这些值建立一个迭代器。
测试代码好下:
var it=values(1,4,1,4,2,1,3,5,6);
it.next();//1
it.next();//4
it.next();//1
分析:由于values函数需要接收任意多个参数,这里就需要用到上一节讲到的构建可变参数的函数的方法。然后里面的迭代器对象来遍历arguments对象的元素。
初步编码
function values(){
var i=0,n=arguments.length;
return {
hasNext:function(){
return i<n;
},
next:function(){
if(this.hasNext()){
return arguments[i++];
}
throw new Error("已经到达最后啦");
}
}
}
用上面的测试代码进行测试
var it=values(1,4,1,4,2,1,3,5,6);
it.next();//undefined
it.next();//undefined
it.next();//undefined
错误分析
代码运行结果并不正确,下面就对初始的编码程序进行分析。
function values(){
var i=0,n=arguments.length;//这里没有错误,arguments是values里的内置对象
return {
hasNext:function(){
return i<n;
},
next:function(){
if(this.hasNext()){
return arguments[i++];//错误出现在这里,arguments是next方法函数的内置对象。
}
throw new Error("已经到达最后啦");
}
}
}
这里的指代错误,很像是另一个让人头痛的对象this。处理this的指向时,通常是使用变量和保存正确的this。然后在其它地方使用这个变量。那么arguments对象的解决方案就出来了,借助一个变量来存储,这样arguments对象的指代就没有问题了。
再次编码
function values(){
var i=0,n=arguments.length,arg=arguments;
return {
hasNext:function(){
return i<n;
},
next:function(){
if(this.hasNext()){
return arg[i++];
}
throw new Error("已经到达最后啦");
}
}
}
运行测试代码
var it=values(1,4,1,4,2,1,3,5,6);
it.next();//1
it.next();//4
it.next();//1
结果和预期的相同。
提示
当引用arguments时当心函数嵌套层级
绑定一个明确作用域的引用到arguments变量,从而可以在嵌套的函数中引用它
附录一:迭代器
迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器上遍历的接口,设计人员无需关心容器的内容。
迭代器UML类图

迭代器js实现
对设计模式了解一点点,但具体项目中,有得多的也就是工厂模式,其它很少用,下面是一个简单的实现,不对的地方,欢迎交流。
代码如下
function List(){
this.data=[];
}
List.prototype={
add:function(){
var args=[].slice.call(arguments)
this.data=this.data.concat(args);
},
remove:function(i){
this.data.splice(i,1);
},
iterator:function(){
return new Iterator(this);
}
}
function Iterator(list){
this.list=list;
this.cur=0;
};
Iterator.prototype={
hasNext:function(){
return this.cur<this.list.data.length-1;
},
next:function(){
if(this.hasNext()){
return this.list.data[this.cur++];
}
throw new Error('已经到底了~');
},
remove:function(){
this.list.remove(this.cur);
}
}
var list1=new List();
var it=list1.iterator();
list1.add(3,2,3,4,1,6,10,8,9);
it.next();//3
it.next();//2
it.next();//3
[Effective JavaScript 笔记]第24条:使用变量保存arguments对象的更多相关文章
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记]第51条:在类数组对象上复用通用的数组方法
前面有几条都讲过关于Array.prototype的标准方法.这些标准方法被设计成其他对象可复用的方法,即使这些对象并没有继承Array. arguments对象 在22条中提到的函数argument ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [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 笔记]第2章:变量作用域--个人总结
前言 第二章主要讲解各种变量作用域,通过这章的学习,接触到了很多之前没有接触过的东西,比如不经常用到的eval,命名函数表达式,with语句块等,下面是一个列表,我对各节的一点点个人总结,很多都是自己 ...
- [Effective JavaScript 笔记]第22条:使用arguments创建可变参数的函数
第21条讲述使用可变参数的函数average.该函数可处理任意数量的参数并返回这些参数的平均值. 如何创建可变参数的函数 1.实现固定元数的函数 书上的版本 function averageOfArr ...
- [Effective JavaScript 笔记]第54条:将undefined看做“没有值”
undefined值很特殊,每当js无法提供具体的值时,就会产生undefined. undefined值场景 未赋值的变量的初始值即为undefined. var x; x;//undefined ...
- [Effective JavaScript 笔记] 第10条:避免使用with
with特性,提供的任何“便利”都更让其变得不可靠和低效率. with语句的用法,可以很方便地避免对对象的重复引用.上面的代码整理成下面的形式 function status(info){ var w ...
随机推荐
- shell中的正则表达式
1.正则与通配符 linux中的通配符是用来匹配文件名的,其匹配是完全匹配.只支持通配符则命令有ls find cp等命令 正则是用来匹配字符串的,是包含匹配.只要搜索的内容在某个字符串中,那么改字符 ...
- Javascript基础系列之(七)函数(定义和调运函数)
函数是一个可以随时运行的语句,简单说,函数是完成某个功能的一组语句,它接受0或者多个参数. 函数的基本语法如下 function functionName([arg0,arg1,......argN] ...
- angular_form
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- Javascript写入txt和读取txt文件示例
1. 写入 FileSystemObject可以将文件翻译成文件流. 第一步: 例: 复制代码 代码如下: Var fso=new ActiveXObject(Scripting.FileSystem ...
- OC基础--self关键字&super关键字
PS:OC中的self关键字可以与C#中的this关键字区分记忆,虽然区别还是很大的. OC中的super关键字指的是父类指针 一.self关键字必须了解的知识: 1.使用场合:只能用在方法中(对象方 ...
- 关闭浏览器后Session失效原因分析
参考文章:http://www.tuicool.com/articles/VNbYjqm 首先需要理解一下几点: 1.Http是无状态的,即对于每一次请求都是一个全新的请求,服务器不保存上一次请求的信 ...
- Jetty+json-lib库抛异常的问题解决过程(java.lang.NoClassDefFoundError: net/sf/json/JSONObject)
一.之前抛异常是将json库改成了fastjson解决的,参见: http://www.cnblogs.com/gossip/p/5369670.html 异常信息: 二.解决步骤 ...
- knockout——官网demo
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- hdu1588 矩阵快速幂
//看了很多的博客 后来队友指点才懂//sum=f(g(0))+f(g(1))+.... //sum=A^(b-1)*|...|.... //要将b-1换,防止出现b=0时有负一,用A^b代替,取下面 ...
- Spring控制Hibernate的缓存机制ehcache
首先在spring.xml中进入bean <prop key="hibernate.cache.use_second_level_cache">true</pro ...