【js学习笔记-053】js中的面向对象技术------枚举类型

来源:互联网 发布:淘宝联盟怎么返现 编辑:程序博客网 时间:2024/06/10 23:18


枚举类型是一种类型,它是值的有限集合,如果值定义为这个类型则该值是可以列出(或称可枚举)的。在C语言中,枚举类型是通过关键字enum声明的。Enum是ECMAScript5的保留字,很有可能js就会内置支持枚举类型。下面实例定来说明js实现枚举类型

 定义一个函数enumeration()。它不是构造函数,它并没有定义一个叫enumeration的类,相反,它是一个工厂方法,每次调用它都会创建并返回一个新类

 

如:创建新的Coin类 Coin.Penny,Coin.Nickel等

var Coin = enumration({Penny:1,Nickel:5,Dime:10,Quarter:25});

var c = Coin.Dime;

c instanceof Coin ; //true instanceof 正常工作

c.constructor == Coin //true 构造函数的属性正学工作

Coin.Quarter+3*Coin.Nickel; //40 将值转换为数字

Coin.Dime==10 //true:转换为数字的例子

Coin.Dime >Coin.Nickel //true: 关系运算符正常工作

String(Coin.Dime)+":"+Coin.Dime//"Dime:10" 强制转换为字符串

 

下面来看一下具体的实现方式

//创建一个新的枚举类型,实参对象表示类的每个实例的名称和值

//返回值是一个构造函数,它标识这个新类

//注意这个构造函数也会抛出异常:不能使用它来创建该类的新实例

//返回的构造函数包含名/值对的映射表

//包含由值组成的数组,以及一个foreach()迭代器函数

function enumeration(namesToValues){

  var  enumeration = function(){throw "Can't Instantiate Enumerations";};

  var  proto = enumeration.prototype = {

    constructor:enumeration,

    toString:function(){return this.name;},

    valueOf:function(){return this.value;},

    toJSON:function(){return this.name}

  }

 

  enumeration.values= []; //用于存放可枚举对象的数组

 for(var name in nameToValues){

   var e = inherit(proto);

   e.name = name;

   e.value = nameToValues[name];

   enumeration[name] = e;

   enumeration.values.push(e);

  }

 

//一个类方法,用来对类的实例进行迭代

enumeration.foreach = function(f,c){

   for(var i=0;i<this.values.length;i++){

      f.call(c,this.values[i]);

    }

};

 

 return enumeration;

 

}

 

下面使用枚举类型定义一副扑克牌

 

定义一个表示“玩牌”的类

 

function Card(suit,rank){

   this.suit = suit;

   this.rank = rank;

}

//使用枚举类型定义花色和点数

Card.Suit = enumeration({Clubs:1,Diamonds:2,Hearts:3,Spades:4});

Card.Rand = enumeration({Two:2,Three:3,Four:4,Five:5,Six:6,Seven:7,Eight:8,Nine:9,Ten:10,Jack:11,Queen:12,King:13,Ace:14});

Card.prototype.toString = function(){

  return this.rank.toString() + "of" +this.suit.toString();

}

 

//比较扑克牌中两张牌的大小

Card.prototype.compareTo = function(that){

  if(this.rank<that.rank) return -1;

  if(this.rank>that.rank)return 1;

 return 0;

}

 

//以扑克牌的玩法规则对牌进行排序的函数

Card.orderByRank = function(a,b){returna.compareTo(b));

 

//以桥牌的玩法规则对扑克牌进行排序的函数

Card.orderBySuit = function(a,b){

  if(a.suit<b.suit) return -1;

  if(a.suit>b.suit)return 1;

  if(a.rank<b.rank)return -1;

  if(a.rank>b.rank)return 1;

  return 0;

};

 

//定义用以表示一副标准扑克牌的类

function Deck(){

  var cards = this.cards = [];

  Card.Suit.foreach(function(s){

       Card.Rank.foreach(function(r){

        cards.push(new Card(s,r);

      });

   });

}

 

//洗牌的方法,重新洗牌并返回好的牌

Deck.prototype.shuffle = function(){

   //遍历数组中的每个元素,随机找出牌面最小的元素,并与当前遍历元素交换

   var deck = this.cards,len = deck.length;

   for(var i=len-1;i>0;i--){

      var r = Math.floor(Math.random()*(i+1)),temp;

     temp = deck[i],deck[i] = deck[r];,deck[r] = temp;

    }

 return this;

}

 

//发牌方法:返回牌的数组

Deck.prototype.deal = function(n){

  if(this.cards.length<n) throw "Out of cards";

  return this.cards.splice(this.cards.length-n,n);

};

//创建一副新扑克牌,洗牌并发牌

var deck = (new Deck()).shuffle();

var hand =deck.deal(13).sort(Card.orderBySuit);