js数组的内部实现,迭代器,生成器和内包
js内部实现
在js以外的很多语言中,数组将会隐式占用一段连续的内存空间。
这种隐式的内部实现,使得高效的内存使用及高速的元素方法称为可能,而
在javascript中,数组实体是一个对象,所以通常的实现方式
并不是占用一段连续的内存空间
比较下面2段代码
<script>
//代码1
var arr=[];
for(var i=0;i<1e7;i++){
arr[i]='';
}
//代码2
var arr={};
for(var i=0;i<1e7;i++){
arr[i]='';
}
</script>
根据实现方式的不同,代码1和代码2的执行速度会有所差异,这其实是数组是否使用连续的内存空间的一种体现。
然而如果数组内部总是使用连续的内存空间,下面代码就应该占用多达GB量级的连续内存,不过在一般的实现中,这样的情况不糊发生
<script>
var arr=[];
arr[1e9]='';
</script>
在流行的jsvascript实现中,小型的数组(下标值较小的部分)会占用连续的内存空间,而下标值较大的部分,
则一般会以类似于对象的形式进行处理
此外在js中 也有人提出需要增加Int32Array或Int8Array这类自定义增强功能
数组风格的对象调用Array类的方法
<script>
var fake_arr={0:'zero',1:'one',2:'two',length:3}
fake_arr.join(',');//Uncaught TypeError: undefined is not a function
p(Array.join(fake_arr,','));//zero,one,two firefox可以运行 其它浏览器可能报错
Array.push(fake_arr,'three');
p(fake_arr.length);//4
p(Array.join(fake_arr,'_'));//zero_one_two_three
//另外一种
p(Array.prototype.join.call(fake_arr,'-')); // zero-one-two-three 更多浏览器支持了
</script>
迭代器
一种专门为循环操作设计的对象
在javascript中有Iterator类这样一个自定义增强功能。
可以通过构造函数调用或Iterator函数的调用来生成一个对象实例,这时需要将想要枚举的目标对象传递个它的第一个参数
在迭代器对象中含有一个next方法,可以从对象或元素的集合中返回下一个所需的元素
下面代码在firefox下正常运行,在其他浏览器中可能出问题
<script>
var arr=['zero','one','two'];
var it=new Iterator(arr,true);
p(it.next());//0 单个元素
p(it.next());//1
p(it.next());//2
p(it.next());//uncaught exception: [object StopIteration]
//如果第二个参数为false
var it=new Iterator(arr,false);
p(it.next());//[0 ,zero ] 数组
p(it.next());//1 one
p(it.next());//2 two
p(it.next());//uncaught exception: [object StopIteration]
</script>
对Iterator使用for in
<script>
var arr=['zero','one','two'];
var it=new Iterator(arr,false);
for(var item in it){
for(var k in item){
p(k+":"+item[k]);
}
p("--------------------------------------")
}
/*输出
0:0
1:zero
--------------------------------------
0:1
1:one
--------------------------------------
0:2
1:two
--------------------------------------
*/
</script>
对于已经存在的对象或数组来说,使用Iterator没有太大作用
for in等语句已经足够
使用场景:自定义迭代器
代码如下(测试时在firefox下好使)
<script>
//迭代器的目标对象
function Factorial(max){
this.max=max;
}
//自定义迭代器
function FactorialIterator(factorial){
this.max=factorial.max;
this.count=this.current1=1;
}
//迭代器的实现
FactorialIterator.prototype.next=function(){
if(this.count>this.max){
throw StopIteration;
}else{
return this.current1*=this.count++;
}
}
//将Factorial与FactorialIterator相关联
//__iterator__属性是一种特殊属性
Factorial.prototype.__iterator__=function(){
return new FactorialIterator(this);
} var obj=new Factorial(5);
for(var n in obj){
p(n)
}
/*
结果
1
2
6
24
120
*/
</script>
生成器
和迭代器一样,生成器(Generator)也是javascript自定义的增强功能,其作用是帮助执行循环处理
从表面上看,生成器就像一个普通的函数.生成器与普通函数的不同之处在于是否在内存进行yield调用。
一个函数如果在内部进行yield调用,它就是一个隐式的生成器
输出阶层的函数
<script type="application/javascript;version=1.7">
function jc_prnt(max){
var cur=1;
for(var n=1;n<=max;n++){
cur*=n;
p('curl='+cur);
}
}
jc_prnt(5);
/*输出
curl=1
curl=2
curl=6
curl=24
curl=120
*/
</script>
如果在js_print函数里的p(打印)函数之前调用yield
就变成了如下代码
<script type="application/javascript;version=1.7">
function jc_prnt(max){
var cur=1;
for(var n=1;n<=max;n++){
cur*=n;
yield(cur);
p('curl='+cur);
}
}
var g=jc_prnt(5);
p(g.next());//1
p(g.next());//curl=1 2
p(g.next());//curl=2 6
p(g.next());//curl=6 24
p(g.next());//curl=24 120
p(g.next());//curl=120 报错
</script>
由于从内部看迭代生成器是一个迭代器,所以可以将next方法调用隐藏在for in循环的内部
js_print函数同上
<script type="application/javascript;version=1.7">
var g=jc_prnt(5);
for(var n in g){
p(n,'------------');
}
/*
1
------------
curl=1
2
------------
curl=2
6
------------
curl=6
24
------------
curl=24
120
------------
curl=120
*/
</script>
可将生成器理解为一种由于yield而处于停滞状态的函数。
在调用next时,生成器的循环将执行一次,更确切的说,这一执行过程与循环没有关系,只是执行生成器的代码直至下一次调用yield
处
数组的内包
数组的内包是一种在通过生成器生成数组时的功能
<script type="application/javascript;version=1.7">
function jc_prnt(max){
var cur=1;
for(var n=1;n<=max;n++){
cur*=n;
yield(n);
}
}
var arr=[i for each (i in jc_prnt(5))];
p(arr);//数组 1,2,3,4,5
//也可过滤
var arr=[ i for each (i in jc_prnt(5)) if (i>3)];
p(arr);//4,5 数组
</script>
注意,上面所有的代码 由于是javascript里的自定义增强功能有的浏览器还不支持,在firefox下运行良好,可以在firefox下测试
js数组的内部实现,迭代器,生成器和内包的更多相关文章
- Python迭代器生成器,模块和包
1.迭代器和生成器 2.模块和包 1.迭代器 迭代器对象要求支持迭代器协议的对象,在Python中,支持迭代器协议就是实现对象的__iter__()和__next__()方法. 其中__it ...
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- Python学习笔记——基础篇【第四周】——迭代器&生成器、装饰器、递归、算法、正则表达式
目录 1.迭代器&生成器 2.装饰器 a.基本装饰器 b.多参数装饰器 3.递归 4.算法基础:二分查找.二维数组转换 5.正则表达式 6.常用模块学习 #作业:计算器开发 a.实现加减成熟及 ...
- 小兔JS教程(四)-- 彻底攻略JS数组
在开始本章之前,先给出上一节的答案,参考答案地址: http://www.xiaotublog.com/demo.html?path=homework/03/index2 1.JS数组的三大特性 在J ...
- Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化
本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...
- python杂记-4(迭代器&生成器)
#!/usr/bin/env python# -*- coding: utf-8 -*-#1.迭代器&生成器#生成器#正确的方法是使用for循环,因为generator也是可迭代对象:g = ...
- python 迭代器 生成器
迭代器 生成器 一 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...
- 页面循环绑定(变量污染问题),js面向对象编程(对象属性增删改查),js字符串操作,js数组操作
页面循环绑定(变量污染问题) var lis = document.querySelectorAll(".ul li") for ( var i = 0 ; i < lis. ...
- 11、js 数组详细操作方法及解析合集
js 数组详细操作方法及解析合集 前言 在开发中,数组的使用场景非常多,平日中也涉及到很多数组的api/相关操作,一直也没有对这块内容进行一块整理总结,很多时候就算用过几次这个api,在开发中也很容易 ...
随机推荐
- POJ 3422 Kaka's Matrix Travels 【最小费用最大流】
题意: 卡卡有一个矩阵,从左上角走到右下角,卡卡每次只能向右或者向下.矩阵里边都是不超过1000的正整数,卡卡走过的元素会变成0,问卡卡可以走k次,问卡卡最多能积累多少和. 思路: 最小费用最大流的题 ...
- [ZOJ 3839] Poker Face (递归)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3839 题目大意:画脸..每张脸是上一个脸倒过来加上眼睛.. 注意 ...
- [ZOJ 1009] Enigma (模拟)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1009 题目大意:给你三个转换轮,只有当第一个转换轮转动一圈后第二 ...
- [HDU 3689]Infinite monkey theorem (KMP+概率DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3689 黄老师说得对,题目只有做wa了才会有收获,才会有提高. 题意:一个猴子敲键盘,键盘上有n个键,猴 ...
- VS2013配置WTL90_4140_Final
网上关于WTL的文章,尤其是中文的文章不多,根据收集的资料整理出了VS2013安装WTL的方法. 1.下载.文件很小的,地址:http://sourceforge.net/projects/wtl/f ...
- 403 Forbidden
http://baike.baidu.com/link?url=JJXC_XqJ2d-twe1dhbLUiRgvZU5OfneRURT4LvrtWBqv9Av4J0GPOlwk3KQuRx4Hzu4N ...
- sql查询,如何增加一列
select * from (select 'finish_order_info' as table_name,count(1)as num from fraudorder.finish_order_ ...
- linux下USB转串口驱动的安装
ubuntu10.04,usb串口用的是moxa 1110 搞了半天没有驱动... 去官方下了个:http://www.moxa.com/support/sarch_result.aspx?type= ...
- jsp页面
//获取根目录 ${pageContext.request.contextPath} //(父页面提交,嵌入页面显示)提交表单,设置响应方法和返回结果页面显示在frame中 <input typ ...
- Android:Activity的跳转
// 实际开发中常用的方法 Intent intent = new Intent(); intent.setClass(MainActivity.this, LoginActivity.class); ...