Reputation: 11247
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).
Upvotes: 1
Views: 102
Reputation: 239443
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.
Upvotes: 2
Reputation: 234795
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.
Upvotes: 0