//集合类Set( ES6标准才有的类,目前兼容性较差)
//自定义集合类:
extend = function (o,p){ //定义一个复制对象属性的类函数
for(var x in p){ o[x] = p[x]; }
return o;
};
function Set(){
this.values = {};
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.values.hasOwnProperty(str)){ //判断是否在集合中
this.values[str] = val; //按字符串和值对添加进集合
this.n++; //集合中的值+1
}
}
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.values[str];
this.n--;
}
}return this;
};
Set.prototype.contains = function(value){
return this.values.hasOwnProperty(Set._v2s(value));
};
Set.prototype.size = function(){ return this.n;};
//遍历集合中的所有元素,在指定的上下文context中对每个元素执行函数f
Set.prototype.foreach = function(f,context){
for(var s in this.values){
if(this.values.hasOwnProperty(s)){
f.call(context,this.values[s]);
}
}
}; //作用:对任意对象都返回一个字符串,针对不同对象返回不同的字符串,对于同一对象返回相同字符串
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创建一个不可枚举且只读的属性,用来存放id
function objectId(o){
var prop = '|**objectid**|';
if(!o.hasOwnProperty(prop)) o[prop] = Set._v2s.next++;
return o[prop];
}
};
Set._v2s.next = 100;
//==类工厂,子类,父类===
function fromSubclass(superclass,f){
var c = function(){
superclass.apply(this,arguments); //调用父类的构造函数
};
var proto = c.prototype =Object.create(superclass.prototype);
proto.constructor = c;
proto.add = function(){
for(var i=0;i<arguments.length;i++){
var v=arguments[i];
if(!f(v)) throw ('value'+v+'!');
}
superclass.prototype.add.apply(this,arguments); //调用父类的原型方法
};
return c;
}
var f1 = function(x){return typeof x === 'string';};
var f2 = function(x){return typeof x === 'function';};
var StringSet = fromSubclass(Set,f1); //可以很方便的根据不同的父类来创建子类,只需改一下参数即可
var MySet = fromSubclass(Set,f2);
//===定义并立即调用
var NonNullSet = (function(){
var superclass = Set; //只需改此值,就可以继承自不同的父类
return extend(
function(){ superclass.apply(this,arguments)}, //构造函数指代类本身
{
add:function () {
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] == null) {
throw new Error('can not add null or undefined');
}
}
return superclass.prototype.add.apply(this, arguments);
}
}
);
}());
//======='组合优于继承': 使用组合代替继承========================================
//只需创建一个单独的ChildClass子类,利用这个类的实例来创建继承自不同的superClass和执行不同的func方法
var ChildClass = extend(
function ChildClass(superClass,func){
this.set = superClass;
this.filter = func;
},
{
add:function(){
if(this.filter){
for(var i = 0;i<arguments.length;i++){
var v = arguments[i];
if(!this.filter(v)){
throw new Error('ChildClass:value '+v+'null');
}
}
this.set.add.apply((this.set,arguments));
return this;
}
},
remove:function(){
this.set.remove.apply(this.set,arguments);
return this;
},
contains:function(v){return this.set.contains(v);},
size:function(){return this.set.size();},
foreach:function(f,c){this.set.foreach(f,c);}
}
);
//==
var s = new ChildClass(new Set(),function(x){return x!== null;});
var t = new ChildClass(s,function(x){return !(x instanceof Set);});
//=======抽象类和非抽象类的层次结构========================================
// 抽象方法
function abstractmethod() { throw new Error("abstract method"); }
//抽象类
function AbstractSet() { throw new Error("Can't instantiate abstract classes");}
AbstractSet.prototype.contains = abstractmethod; //抽象方法contains var AbstractWritableSet = extend(
function() { throw new Error("Can't instantiate abstract classes"); },
{
add: abstractmethod,
remove: abstractmethod,
union: function(that) {
var self = this;
that.foreach(function(v) { self.add(v); });
return this;
},
intersection: function(that) {
var self = this;
this.foreach(function(v) { if (!that.contains(v)) self.remove(v);});
return this;
},
difference: function(that) {
var self = this;
that.foreach(function(v) { self.remove(v); });
return this;
}
});

JavaScript学习笔记-自定义集合类的更多相关文章

  1. JavaScript学习笔记- 自定义滚动条插件

    此滚动条仅支持竖向(Y轴) 一.Css /*这里是让用户鼠标在里面不能选中文字,避免拖动的时候出错*/ body { -moz-user-select: none; /*火狐*/ -webkit-us ...

  2. JavaScript学习笔记-自定义滚动条

    这是一个基本实现思路,如果有新手和我一样没什么事,喜欢瞎研究话,可以参考下. 一.Html <div class="scroll_con"> <div class ...

  3. JavaScript:学习笔记(2)——基本概念与数据类型

    JavaScript:学习笔记(2)——基本概念与数据类型 语法 1.区分大小写.Test 和 test 是完全不同的两个变量. 2.语句最好以分号结束,也就是说不以分号结束也可以. 变量 1.JS的 ...

  4. Java程序猿的JavaScript学习笔记(汇总文件夹)

    最终完结了,历时半个月. 内容包含: JavaScript面向对象特性分析,JavaScript高手必经之路. jQuery源代码级解析. jQuery EasyUI源代码级解析. Java程序猿的J ...

  5. Java程序猿的JavaScript学习笔记(8——jQuery选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  6. Java程序猿JavaScript学习笔记(2——复制和继承财产)

    计划和完成在这个例子中,音符的以下序列: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaSc ...

  7. Java程序猿的JavaScript学习笔记(3——this/call/apply)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  8. Java程序猿JavaScript学习笔记(4——关闭/getter/setter)

    计划和完成这个例子中,音符的顺序如下: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScr ...

  9. Java程序猿JavaScript学习笔记(14——扩大jQuery UI)

    计划和完成这个例子中,音符的顺序如下: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScr ...

随机推荐

  1. hdu3635 Dragon Balls(带权并查集)

    /* 题意:有N个城市, 每一个城市都有一个龙珠(编号与城市的编号相同),有两个操作 T A ,B 将标号为A龙珠所在城市的所有的龙珠移动到B龙珠所在城市中! 思路:并查集 (压缩路径的时候将龙珠移动 ...

  2. jQuery.validationEngine.js学习

    项目中使用到了这个插件,抽了个空,看了一下. (function($){ var method ={} $.fn.validationEngine = function(){} $.validatio ...

  3. Cocos2d-x 3.2 学习笔记(十六)保卫萝卜 游戏主循环与定时器

    保卫萝卜~想法一直存在于想法,实战才是硬道理!有想法就去实现,眼高手低都是空谈.   一.游戏主循环GameSchedule      主循环是游戏处理逻辑,控制游戏进度的地方,处理好主循环是很重要的 ...

  4. Java多线程系列--“JUC线程池”05之 线程池原理(四)

    概要 本章介绍线程池的拒绝策略.内容包括:拒绝策略介绍拒绝策略对比和示例 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3512947.html 拒绝策略 ...

  5. 01-Vue.js入门系列

    1.1. Vue简介 Vue是一个前端的双向绑定类的框架,发音[读音 /vjuː/, 类似于 view].新的Vue版本参考了React的部分设计,当然也有自己独特的地方,比如Vue的单文件组件开发方 ...

  6. Azure PowerShell (1) PowerShell整理

    <Windows Azure Platform 系列文章目录> 把之前Azure ASM的PowerShell都整理好了. https://github.com/leizhang1984/ ...

  7. elasticsearch 集群

    elasticsearch 集群 搭建elasticsearch的集群 现在假设我们有3台es机器,想要把他们搭建成为一个集群 基本配置 每个节点都要进行这样的配置: cluster.name: ba ...

  8. C# 异步工具类 及一点小小的重构经验

    2015年新年第一篇随笔, 祝福虽然有些晚,但诚意还在:新年快乐. 今天主要是想分享一异步工具类,在C/S架构中.先进行网络资源异步访问,然后将回调函数 Invoke到UI线程中进行UI处理. 这样的 ...

  9. SignalR入门之从外部访问持久性连接或Hub

    有的时候,需要从外部访问持久性连接或Hub服务. 比如,假设A和B两个客户端正在聊天,那么系统或第三方在不参与聊天的情况需要为他们发送系统消息,那么此时,就需要独立来访问持久性连接或Hub服务. 之前 ...

  10. 解决在android开发中ViewPager中Gallery无法滑动问题

    我的是在viewpager中某个fragment中有gallery... 导致无法滑动,网上找到解决方法. 自定义Gallery. 代码: import android.content.Context ...