0

I am trying to understand Javascript's prototype. I know I can add functions to prototype individually Calculator.prototype.calculate = function(){};, however when I tried setting a new prototype everything fell apart. calc.prototype returns undefined. My question is why can't we set a new Object as the prototype? How to add methods to prototype in bulk instead of adding it one by one ?

var calc = new Calculator();

function Calculator(){
    this.array = [];
    this.results = 0;
}

Calculator.prototype = {

    calculate: function(){  
        try{
        results = eval(this.array.join(''));
        this.array = [results];
        return results; 
        }
        catch(error){
            alert('Wrong arguments provided');
            return this.array.join('');
        }
    },

    isNumber: function(str){
        return !isNaN(parseFloat(str)) && isFinite(str);
    },

    addToOperationsArray: function(str){
        if (this.array.length <= 0 && !this.isNumber(str)){ // Don't add operand before any number.
            return; 
        }

        this.array.push(str);

    },
    clearEverything: function(){
        this.array = [];
    }
};
Yasin Yaqoobi
  • 1,888
  • 3
  • 27
  • 38
  • You can't set a new Object as the prototype because the existing prototype is more than just an empty Object. It includes, for example, the very necessary constructor function. You need to _extend_ the existing prototype; there are many ways to do this, one of which is by using the new [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) method – Hamms Jul 29 '16 at 17:29
  • How did everything fall apart? did you check "calc.__proto__" you'll find that it is there. Obviously, you wouldn't use that - but it is there to show you that it actually is there. – james emanon Jul 29 '16 at 18:04
  • Yeah it is still pointing to Calculator.prototype which is an object with a constructor property which has a prototype that contains all these methods but it is useless because I can't call them. It adds more to the confusion because previously I though that the chain is broken but now I see that those functions are in the prototype, which is somewhere in this black hole that we call javascript. – Yasin Yaqoobi Jul 29 '16 at 18:11
  • I see nothing wrong with the code you're showing us (well the general structure at least). That's one of the many ways to define class methods. Maybe the way you try to use it is the problem? – kuroi neko Jul 30 '16 at 16:42

1 Answers1

1

You are most likely trying to access the (new) prototype object before it is assigned. You are allowed to use the Calculator constructor because function declarations are subject to hoisting. Assignments are not.

The prototype of objects you construct before making those changes will be the object that is the prototype at the time of the call.

// use the default prototype
var test1 = new Test();

// a new prototype is assigned
// objects created from this point will use it
Test.prototype = {
  report: function(){ alert('jah live children yea'); }
};
var test2 = new Test();

test1.report();     // Uncaught TypeError: test1.report is not a function
test2.report();     // alerts


function Test(){}   // hoisted so you can use it before this line

Note that you can use prototype properties with an object that was created prior to them being added to the prototype, if the prototype object itself was not changed, but merely extended.

It is only important that you don't make the calls before the functions are assigned.

var test1 = new Test();

test1.report();     // Uncaught TypeError: test1.report is not a function

// extend the prototype object
// the added property is accessible by existing objects
Test.prototype.report = function(){
  alert('jah live children yea');
};

test1.report();     // alerts


function Test(){}
Community
  • 1
  • 1
pishpish
  • 2,574
  • 15
  • 22