我正在用JS构建保龄球记分卡,而我在框架中存储每个碗的得分的方式存在问题。

我这样做是通过将值创建时传递到框架类的实例中,然后使用firstBowl和secondBowl的键将这些值存储在对象中。原因是,我需要从框架外部访问单个碗的值,以便计算罢工和备用奖金。 (我也尝试使用数组,并且遇到了与下面详述的相同的问题。)

我遇到的问题是,在测试中,我正在创建一个罢工框架,该罢工框架的firstBowl值为10,secondBowl值为0,并将其链接到可以在测试中其他位置调用的变量。但是,当我打电话给罢工时,我发现firstBowl和secondBowl值都已设置为0,总分仍为10。如果在测试中创建一个新的罢工框架,它的功能将达到我的预期。

这是我的Frame类的代码:

function Frame(firstBowl, secondBowl = 0){

  var bowls = new Object();
  bowls.firstBowl = firstBowl;
  bowls.secondBowl = secondBowl;

  this.score = 0;

  this.init = function(){
    if (bowls.firstBowl + bowls.secondBowl > 10) {
      throw new Error("Illegal Score: Can't be greater than 10")
    };
    this.score = bowls.firstBowl + bowls.secondBowl
  };

  this.init();

  Frame.prototype.getScore = function(){
    return this.score;
  };

  Frame.prototype.getStatus = function(){
    if(bowls.firstBowl === 10) {
      return "strike";
    }else if(bowls.firstBowl != 10 && this.getScore() === 10) {
      return "spare";
    }else if(this.getScore() === 0) {
      return "gutter";
    };
    return;
  };

  Frame.prototype.getBowls = function(){
    return bowls;
  };
};


这是有问题的测试:

describe("Frames", function() {

  var frame;
  var strike;
  var spare;
  var gutter;

  beforeEach(function(){
    frame = new Frame(1, 1);
    strike = new Frame(10);
    spare = new Frame(5,5);
    gutter = new Frame(0,0);
  });

  it("Returns Frame Status as Strike when first bowl is 10", function(){
    expect(strike.getStatus()).toEqual("strike")
  });

});


这是与在测试中调用框架相比,框架在beforeEach函数中初始化时的控制台日志:

frameSpec.js:11 --Initialised-
frameSpec.js:12 Frame {score: 10, init: function}
frameSpec.js:13 Object {firstBowl: 10, secondBowl: 0}
frameSpec.js:14 strike
frameSpec.js:15 ------end-------


frameSpec.js:37 ---In Test--
frameSpec.js:38 Frame {score: 10, init: function}
frameSpec.js:39 Object {firstBowl: 0, secondBowl: 0}
frameSpec.js:40 spare
frameSpec.js:41 ------end-------


我试图四处搜寻并努力寻找任何东西(老实说,我试图简洁地表达我的问题很困难)

任何帮助或见识将不胜感激。我确定我只是错过了一些非常明显的东西。

最佳答案

您的代码中有不必要的关闭:

//simplified:
function Frame(first,second){
  Frame.prototype.getStatus=function(){//assigned to prototype => all instances
    return first+second;//these get bound whenever frame is called
  };
}


那它做什么

var a=new Frame(0,0);
a.getStatus()//0
var b=new Frame(1,1);
b.getStatus();//2
a.getStatus();//2 == b.getStatus


因此,实际上getStatus总是返回最后一个元素的值。使其成为本地对象的属性:

this.getStatus=function(){}


或使其成为静态原型并通过上下文传递所有值:

function Frame(a,b){ this.a=a; this.b=b}
Frame.prototype.getStatus=function(){ return this.a+this.b};




简化代码:

function Frame(one,two){
  if(one+two>10) throw new Error("wrong args");
  this.one=one;
  this.two=two||0;
  this.score=this.one+this.two;
  this.status=["gutter","strike"][this.score/10] || "regular";
  if(this.score==10 && this.one != 10) this.status=" spare";
}


console.log(new Frame(10));


http://jsbin.com/rohanihawo/1/edit

09-04 16:09