扑克牌 ---JavaScript enumeration

这个是JavaScript权威指南里example 9-7 的例子,在这里与大家交流一下

/**

 * 此方法将返回一个新对象(继承于传来的参数)
 * @param {} p
 * @return {}
 */
function inherit(p) {
         if(p == null)    //其实这里可以写成if(p);if可以检测出undefined,null,false,"",0,NaN
                   throwTypeError();
         if(Object.create) {  //这里检查当前ECMAScript 版本,如果有create方法了则直接返回新对象,否则就用下来的方法来创建新对象
                   returnObject.create(p);
         }
         vart = typeof p;   //typeof  可以检查出 右边 参数的对象类型
         if(t !== "object" && t !== "function")
                   throwTypeError();
         functionf() {
         }
         f.prototype= p;  //这个句话是继承的关键,表名 f 继承于 p  
         returnnew f();
}


function enumeration(namesToValues) {
         /**
          *这function书上是这样解释的
          *This is the dummy constructor function that will be the return value.
          *至于你懂不懂,反正我不懂,懂的你希望能留言一下,解释一下,谢谢
          */
         varenumeration = function() {
                   throw"Can't Instantiate Enumeration";
         };
/**
 * 这是对enumeration的扩展,我目前是这么理解的,扩展了:增加了一个构造function和几个方法
 * 这里的proto 是一个引用,指向enumeration
 * @type 
 */
         varproto = enumeration.prototype = {
                   constructor: enumeration,  //这里的enumeration是不是指的是上面enumeration的引用呢?有什么作用?
                   toString: function() {
                            returnthis.name;
                   },
                   valueOf: function() {
                            returnthis.value;
                   },
                   toJson: function() {
                            returnthis.name;
                   }
         };


         enumeration.values= [];  //扩展,增加了一个values的数据对象
/**
 * 这是一个遍历方法,比如这里namesToValues为{Club : 1,Diamond : 2},那么name的值分别为“Club”与”Diamond“
 */
         for(name in namesToValues) {
                   vare = inherit(proto);  //产生新对象 ,都继承于proto
                   e.name= name;
                   e.value= namesToValues[name]; // 根据name来取得namesToValues里的name的值,如Map
                   enumeration[name]= e; // 在enumeration增加一个name的属性(这就是动态语言的特点吧)
                   enumeration.values.push(e);//加到values里去,保存起来
         }


         enumeration.foreach= function(f, c) {
                   for(var i = 0; i < this.values.length; i++) {
                            f.call(c,this.values[i]); // 每次调用c对象里的f方法,并传入enumeration.values里的值
                   }
         };
         returnenumeration;


}
/**
 * 这是一个扑克牌的例子
 * @param {} suit   为方块、红星之类的
 * @param {} rank  就是指2、3、4....K、A
 */
function Card(suit, rank) {
         this.suit= suit;
         this.rank= rank;
}


//这里算是执行程序的入口吧
Card.Suit = enumeration({
                            Club: 1,
                            Diamond: 2,
                            Heart: 3,
                            Spades: 4

                   });

//执行后应该是这样;亲,你能看懂吗?

 

Card.Rank = 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(){
         returnthis.rank.toString() + "   of    " +this.suit.toString();
};


Card.prototype.compareTo = function(that){
         if(this.rank< this.rank) return -1;
         if(this.rand> this.rank) return 1;
         return0;
};


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;
         return0;
};
/**
 * 这是一个遍历的方法
 * cards里就放着4 * 13 个对象
 * 意思就是得到全部扑克牌,比如new Deck();就可以得到4 * 13个牌了
 * 这应该就是Deck的构造函数吧
 * 这里的foreach是上面定义的,有两个参数,可这里都只传一个参数,第二个参数则为null,传null会有什么影响呢?求指导...
 */
function Deck(){
         varcards = this.cards = [];
         Card.Suit.foreach(function(s){//外层为红心、黑桃等4种牌
                   Card.Rank.foreach(function(r){//内层为2、3、4、5....K、A
                            cards.push(newCard(s,r));
                   });
         });     
}
/**
 * 这方法是用来打乱牌的(洗牌)
 * 这里的Math.random() * (i +1) 写得不错,0 < Math.random() < 1 那里整个值的范围为  0 到 i 了,不懂的请在纸上写写看,你就容易明白了
 * @return {} 
 */
Deck.prototype.shuffle = function(){
         vardeck = this.cards, len = deck.length;
         for(vari = len -1; i > 0; i --){
                   varr = Math.floor(Math.random() * (i +1)),temp;  //Math.floor()是去一法的,比如0.9则取0,5.5则取5;这与Math.ceil()相反
                   temp= deck[i],
                   deck[i]= deck[r],
                   deck[r]= temp;
         }
         returnthis;  //return this 是为了方法链,如deck.deal(13).sort(Card.orderBySuit),执行顺序为从左到右
};
/**
 * 在这里的意思是删除第n个后的扑克牌
 * @param {} n
 * @return {}
 */
Deck.prototype.deal = function(n){
         if(this.cards.length< n){
                   throw"Out of cards";
         }
         returnthis.cards.splice(this.cards.length - n, n);  //splice(m,n)是从数组里删除数据,从第m个开始(包括m),删除n个数据;
};


var deck = (new Deck()).shuffle(); //得到全部扑克牌后,洗牌
var iii = deck.deal(13);
var hand = deck.deal(13).sort(Card.orderBySuit); 
for(var i = 0; i < hand.length; i ++){
         console.log(hand[i].toString());
}
/**
 * 删除每13张后全部的扑克牌,意思只要13张牌,然后排序,这里的Card.orderBySuit,我一开始我不懂, 后来我懂了,不懂的同鞋可以去看看js 里的sort的用法
 * arrayObject.sort(sortby)         sortby可选。规定排序顺序。必须是函数
 *     若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
 *          若 a 等于 b,则返回 0。
 *          若 a 大于 b,则返回一个大于 0 的值。
 *
 * 后面的for是我自己加上去了,可以打印出手上是哪13张牌

发布了23 篇原创文章 · 获赞 0 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章