2

I am working through TestFirst JavaScript and hit a wall of confusion. Both of these code snippets pass the tests but I am confused on the difference or if there is even a main difference between these two solutions. Overall, I believe what the test is asking me to create is a 'Constructor' Function.

Tests cases:

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);
    });
});

Solution 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;
  };

};

Solution 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];
        }       
    }
};

My main question is in solution 1, this is a constructor function. What I don't know is if when we create a new calculator with it, ex:

var calculatorSolOne = new Calculator();

Are all the properties on calculatorSolOne or are they inheriting these properties from the prototype of Calculator?

Using solution 2, where are the properties stored, I believe for solution 2 they are stored on the Calculator.prototype and the only value on the actual object is the number value (the rest of the properties have to look at Calculator.prototype and get their properties from the prototype object).

HelloWorld
  • 10,529
  • 10
  • 31
  • 50
  • Since there are no properties on the prototype in your solution 1, how could the be inherited? – Bergi Apr 10 '14 at 13:19
  • possible duplicate of [Use of 'prototype' vs. 'this' in Javascript?](http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript) – Bergi Apr 10 '14 at 13:20
  • Maybe the following answer can help you understand the difference between prototype and instance specific members: http://stackoverflow.com/a/16063711/1641941 You are destroying the `prototype.constructor` property by setting the prototype in the way you do that can lead to unexpected results when other people use your code and expect the constructor to point to the actual constructor. – HMR Apr 10 '14 at 14:06

2 Answers2

2

In the first case, all the functions and the accumulator will be on calculatorSolOne object only. Whenever you create an object, new function objects are constructed. There is no inheritance involved here. So, this leads to degraded performance and not recommended.

In the second case, when you create an object, only the variable accumulator will be on calculatorSolOne object, all the functions will be in prototype object only. When you try to access them, JavaScript checks the prototype chain, as it doesn't find the attribute in the current object.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
0

In the first case, when you construct a new Calculator, the new object has new instances of the functions. Since all copies of each function are simply verbatim copies, this is a waste, which is why the prototype-based solution is preferable. You are correct about how solution 2 works: each instance of Calculator has its own number and there is a single copy of each member function shared among all instances.

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521