JavaScript实现通过的集合类

时间:2021-06-16 15:25:17

  集合是一种数据结构,用以表示非重复值的无序集合。集合的基础方法包括添加值、检测值是否在集合中,这种集合需要一种通用的实现,以保证操作效率。

  JavaScript的对象是属性名以及与之对应的值的基本集合。用JavaScript实现了一个通用的Set类,它实现了从js值到唯一字符串的映射,然后将字符串用做属性名。对象和函数都不具备如此简明可靠的唯一字符串表示。

  因此集合类必须给集合中的每一个对象或函数定义一个唯一的属性标识。

 //通用集合类
function Set(){ //这是一个构造函数
this.value={}; //集合数据保存在对象的属性里
this.n=0; //集合中值的个数
this.add.apply(this,arguments); //把所有参数都添加进这个集合
} //将每个参数都添加至集合
Set.prototype.add=function(){
for(var i=0;i<arguments.length;i++){ //遍历每个参数
var val=arguments[i]; //待添加到集合中的值
var str=Set._v2s(val); //把它转换为字符串
if(!this.value.hasOwnProperty(str)){ //如果不在集合中
this.value[str]=val; //将字符串和值对应起来
this.n++; //集合中值的计数
}
}
return this; //支持链式方法调用
} //从集合中删除元素,删除元素由参数指定
Set.prototype.remove=function(){
for(var i=0;i<arguments.length;i++){
var str=Set._v2s(arguments[i]);
if(this.values.hasOwnProperty(str)){
delete this.value[str];
this.n--;
}
}
return this;
} //遍历集合中的所有元素,在指定上下文中调用f
Set.prototype.foreach=function(f,context){
for(var s in this.values){
if(this.value.hasOwnProperty(s)) //忽略继承的属性
f.call(context,this.value[s]);
}
} //这是一个内部函数,用以将任意JavaScript值和唯一的字符串对应起来
Set._v2s=function(val){
switch(val){
case undefined: return 'u';
case null: return 'n';
case true: return 't';
case false: return 'f';
default: switch(typeof val){
case 'number': return '#'+val;
case 'string': return '"'+val;
default: return '@'+objectId(val);
}
} //对任意对象来说,都会返回一个字符串
//针对不同的对象,这个函数会返回不同的字符串
//对于同一个对象的多次调用,总是返回相同的字符串
//为了做到这一点,它给o创建了一个属性,在ES5中,这个属性是不可枚举且是只读
function objectId(o){
var prop="|**objectid**|"; //私有属性,用以存放id
if(!o.hasOwnProperty(prop)) //如果对象没有id
o[prop]=Set._v2s.next++; //将下一个值赋给它
return o[prop]; //返回这个id
}
};
Set._v2s.next=100; //设置初始id值

  来源于《JavaScript权威指南 9.6.1》