试图了解nodeJS和javascript对象

我试图写一个对象的快速示例,以及该对象的一些原型,并且从代码中获得了一些意想不到的结果。 我正在处理两个文件,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 [] 

看起来我从卡片洗牌中得到了正确的结果,但是当我回头看看“ 卡片 ”包含的内容时,即使设置了值,我也会得到意想不到的结果。 我有一些麻烦,理解这是为什么。 另外,以这种方式返回结果的可怜forms,还是应该像使用getCards方法一样使用传统的“返回”语句?

提前致谢。

其他人已经回答了你的实现的具体问题(可能与你的callback中的价值)。 我发现的是,简化实现方式更简单:

  1. 没有理由在这里使用recursion。 一个简单的while循环就足够了。 这使得实现更简单,更高效,更容易debugging。

  2. 没有理由在这里使用callback通知完成。 这里的所有代码是同步的。 你可以调用函数,当它返回时,结果就完成了。 callback对于进度通知或asynchronous事件未来一段时间的通知很有用。 当所有的代码都是同步的时候,使用callback来传递结果只是编写代码的一种更复杂的方式,并不是必需的或有帮助的。

  3. 程序strict模式。 这会把你的编程错误立即标记为一个错误,因为this错误可能是undefined并且this错误会导致一个直接的错误,而不是做错误的事情,而不是告诉你这个错误。

  4. 总是在它们前面使用var声明局部variables,以避免创build隐含的全局variables,这会导致您在recursion或asynchronous代码中出现问题。

这是一个更简单的实现:

 "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/

当你在callback范围内时, this.cards指的是(和创build)callback函数的cards属性。 它最初不是这个范围,所以当你转过身来尝试logging它的时候,你正在logging那个数组,你把所有东西都拼出来了。

有几种方法可以使其工作。 你可以捕获上面的this ,像var self = this东西,并在callback中使用selfvariables。 您可以bind()callback函数bind()为预期的值。 或者,您可以通过返回return_deck来设置input_cards = return_deck来代替callback,或者您认为合适。 在这种情况下,callback并不是完全必要的,因为你所做的一切都是asynchronous的,无论如何,它都会以相同的方式stream动。

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

另外,这里有一些很好的阅读