试图了解nodeJS和javascript对象

时间:2014-10-27 20:06:46

标签: javascript node.js class object

我试图写一个对象的快速示例,以及该对象的一些原型,我从代码中得到了一些意想不到的结果。我正在处理两个文件,index.js和cards.js 基本思想是实例化一个名为" deck"然后在该对象上调用一些方法。这是我的代码

cards.js

//constructor
function cardsClass() {
        this.cards = [
                { suit: 'heart', number: 1, name: 'ace' },
                { suit: 'heart', number: 10, name: 10 },
                { suit: 'heart', number: 11, name: 'jack' },
                { suit: 'heart', number: 12, name: 'queen' },
                { suit: 'heart', number: 13, name: 'king' }
        ];
}

//class method
cardsClass.prototype.getCards = function() {
        return this.cards;
}

cardsClass.shuffle_helper = function (input_cards, return_deck, callback) {

        if (input_cards.length !=0) {
                index = Math.floor(Math.random() * input_cards.length);

                if (input_cards[index]) {
                        return_deck.push(input_cards[index]);
                        input_cards.splice(index, 1);
                }

                cardsClass.shuffle_helper(input_cards, return_deck, callback);
        }

        else {
                callback(null, 'success');

        }

}

//class method
cardsClass.prototype.shuffle = function (callback) {
        //set up a temp deck...
        var return_deck = [];

        cardsClass.shuffle_helper(this.cards, return_deck, function (err, results) {
                this.cards = return_deck;

                callback(null, this.cards);
        });
}

module.exports = cardsClass;

index.js

var cards = require('./cards.js');

deck = new cards();

console.log( deck.getCards() );

deck.shuffle(function (err, results){

        console.log ('our results of a deck.shuffle');
        console.log (results);

});

console.log ('and this is what our getCards function returns');
console.log( deck.getCards() );

console.log ('looking at deck.cards');
console.log (deck.cards);

运行此代码后得到的结果如下

$ node index.js
[ { suit: 'heart', number: 1, name: 'ace' },
  { suit: 'heart', number: 10, name: 10 },
  { suit: 'heart', number: 11, name: 'jack' },
  { suit: 'heart', number: 12, name: 'queen' },
  { suit: 'heart', number: 13, name: 'king' } ]
our results of a deck.shuffle
[ { suit: 'heart', number: 1, name: 'ace' },
  { suit: 'heart', number: 11, name: 'jack' },
  { suit: 'heart', number: 13, name: 'king' },
  { suit: 'heart', number: 10, name: 10 },
  { suit: 'heart', number: 12, name: 'queen' } ]
and this is what our getCards function returns
[]
looking at deck.cards
[]

看起来我从卡片洗牌中得到了正确的结果,但当我回头看看" "包含,我得到意想不到的结果,即使我设置了值。我很难理解为什么会这样。另外,以这种方式返回结果是不好的形式,还是我应该使用传统的" return"像我在getCards方法中的声明?

提前致谢。

2 个答案:

答案 0 :(得分:3)

当您处于回调范围内时,this.cards指的是(并创建)回调函数的cards属性。它最初与this.cards的范围不同,所以当您转身并尝试记录它时,您将记录那个拼接出所有内容的数组。

有几种方法可以让它发挥作用。您可以捕获上面的this,类似var self = this,并在回调中使用self变量。您可以bind()将回调函数this设置为预期值。或者,您可以通过返回return_deck或者您认为合适的方式在最后代替回调设置input_cards = return_deck。在这种情况下,回调并不是完全必要的,因为你所做的一切都不是异步的,并且无论如何它都以相同的方式流动。

cardsClass.shuffle_helper(this.cards, return_deck, function (err, results) {
        this.cards = return_deck; // Not the same "this" as above.

        callback(null, this.cards);
});

另外,这里有关于this

some good reading

答案 1 :(得分:3)

其他人已经回答了您的实施的具体问题(可能在您的回调中使用this的值)。我发现它只是简化实现的方式,更容易:

  1. 这里没有理由使用递归。一个简单的while循环就足够了。这使得实现更简单,更高效,并且更容易调试。

  2. 此处没有理由使用回调来通知完成情况。这里的所有代码都是同步的您可以只调用该函数,当它返回时,结果就完成了。回调对于进度通知或异步事件未来某个时间的通知非常有用。当所有代码都是同步的时,使用回调来传递结果只是编写代码的一种更复杂的方式,并不是必需或有用的。

  3. strict模式进行编程。这可能会立即将您的编程错误标记为错误,因为thisundefinedthis.cards会抛出一个立即错误,而不仅仅是做错了而不是告诉你。

  4. 总是在前面使用var声明局部变量,以避免创建会导致递归或异步代码出现问题的隐含全局变量。

  5. 这是一个更简单的实现:

    "use strict";
    
    //constructor
    function cardsClass() {
            this.cards = [
                    { suit: 'heart', number: 1, name: 'ace' },
                    { suit: 'heart', number: 10, name: 10 },
                    { suit: 'heart', number: 11, name: 'jack' },
                    { suit: 'heart', number: 12, name: 'queen' },
                    { suit: 'heart', number: 13, name: 'king' }
            ];
    }
    
    //class method
    cardsClass.prototype.getCards = function() {
            return this.cards;
    }
    
    //class method
    cardsClass.prototype.shuffle = function (callback) {
        //set up a temp deck...
        var shuffledCards = [];
        while (this.cards.length) {
            var index = Math.floor(Math.random() * this.cards.length);
            shuffledCards.push(this.cards[index]);
            this.cards.splice(index, 1);
        }
        this.cards = shuffledCards;
        return this;
    }
    

    工作演示:http://jsfiddle.net/jfriend00/Lwv4cc3x/