构造函数之间的区别

时间:2014-04-10 13:15:59

标签: javascript

我正在使用TestFirst JavaScript并遇到困惑。这两个代码片段都通过了测试,但我对这些差异感到困惑,或者这两个解决方案之间是否存在重大差异。总的来说,我相信测试要求我创建的是一个'构造函数'功能

测试案例:

describe("Calculator", function() {

  var calculator;

  beforeEach(function() {
    calculator = new Calculator();
  });

  it("initially has 0", function() {
    expect(calculator.value()).toEqual(0);
  });

    it("can add a number", function() {
        calculator.add(2);
    expect(calculator.value()).toEqual(2);
    });

    it("can add two numbers", function() {
        calculator.add(2);
        calculator.add(3);
    expect(calculator.value()).toEqual(5);
    });

    it("can add many numbers", function() {
        calculator.add(2);
        calculator.add(3);
        calculator.add(4);
    expect(calculator.value()).toEqual(9);
    });

    it("can subtract a number", function() {
        calculator.subtract(2);
    expect(calculator.value()).toEqual(-2);
    });

    it("can add and subtract", function() {
        calculator.add(3);
        calculator.subtract(2);
    expect(calculator.value()).toEqual(1);
    });
});

解决方案1:

var Calculator = function(){

  this.accumulator = 0;

  this.value = function(){
    return this.accumulator;
  };

  this.add = function(operand){
    this.accumulator += operand;
  };

  this.subtract = function(operand){
    this.accumulator -= operand;
  };

};

解决方案2:

function Calculator() {
    this.num = 0;
};

Calculator.prototype = {
    value: function() {
        return this.num;
    },
    add: function() {
        for (var i = 0; i < arguments.length; i++){
            this.num += arguments[i];
        }
    },
    subtract: function() {
        for (var i = 0; i < arguments.length; i++){
            this.num -= arguments[i];
        }       
    }
};

我的主要问题是在解决方案1中,这是一个构造函数。我不知道的是,当我们用它创建一个新的计算器时,例如:

var calculatorSolOne = new Calculator();

calculatorSolOne上的所有属性还是从计算器原型继承这些属性?

使用解决方案2,存储属性的位置,我相信解决方案2它们存储在Calculator.prototype中,而实际对象上唯一的值是数值(其余属性必须查看Calculator。原型并从原型对象中获取它们的属性。)

2 个答案:

答案 0 :(得分:2)

在第一种情况下,所有函数和accumulator仅在calculatorSolOne对象上。无论何时创建对象,都会构造新的函数对象。这里没有继承。因此,这会导致性能下降,不推荐使用。

在第二种情况下,当您创建对象时,只有变量accumulator将在calculatorSolOne对象上,所有函数将仅在原型对象中。当您尝试访问它们时,JavaScript会检查原型链,因为它在当前对象中找不到该属性。

答案 1 :(得分:0)

在第一种情况下,当您构造新的Calculator时,新对象具有新的函数实例。由于每个功能的所有副本都是简单的逐字副本,这是一种浪费,这就是为什么基于原型的解决方案更可取的原因。您对解决方案2的工作方式是正确的:Calculator的每个实例都有自己的编号,并且在所有实例之间共享每个成员函数的单个副本。