0

I am going through JS the good parts and come to this example. In the last line I attempt to call upon a method that is defined in the prototype chain of the sum function. I am confused as to why this does not work.

Define the sum function:

var sum = function(){
    var i, sum=0;
    for(i=0;i<arguments.length;i+=1){
        sum += arguments[i];
    }
    return sum;
}

add the method method to the function prototype

Function.prototype.method = function(name, func){
    this.prototype.name = func;
}

use the method method to add an 'add' method to sum

sum.method('add', function(a,b){
    return a + b;
})

The prototype method is clearly defined but I can not access it via the prototype chain:

sum.prototype.add(5,5); //returns 10
sum.add(5,5); //TypeError: sum.add not defined

In the last line why can I not access the method defined in the prototype chain of the sum function?

Shawn Anderson
  • 323
  • 1
  • 2
  • 8
  • Well, your `method` function adds the function to `sum.prototype`, not to `sum`. *"defined in the prototype chain of the sum function"* No its not. The method is defined on `sum.prototype`. This property has nothing to do with sum's own prototype (which is `Function.prototype`: `Object.getPrototypeOf(sum) === Function.prototype`). You seem to confuse the prototype of the function with the prototype of instances of the function when called as constructor. Maybe read https://github.com/getify/You-Dont-Know-JS/tree/master/this%20%26%20object%20prototypes ? – Felix Kling Nov 22 '16 at 21:32
  • `this.prototype.name` should be `this.prototype[name]`. See http://stackoverflow.com/questions/4244896/dynamically-access-object-property-using-variable – Barmar Nov 22 '16 at 21:44
  • @Barmar: Potentially a typo? Otherwise `sum.prototype.add(5,5);` wouldn't work. – Felix Kling Nov 22 '16 at 21:44
  • @FelixKling Not sure what you mean. I'm talking about the assignment `this.prototype.name = func`. He wants to use the value of the `name` parameter, not the literal name `name`. – Barmar Nov 22 '16 at 21:47
  • @Barmar: Right. But in the last example they have `sum.prototype.add(5,5); //returns 10`. That wouldn't work if they had `this.prototype.name = func;` in their code, so I assume they actually use `this.prototype[name] = func;`. – Felix Kling Nov 22 '16 at 21:49
  • @FelixKling I'm sure the tutorial does it right. But it's wrong in the question, that's what my comment is about. – Barmar Nov 22 '16 at 21:55

1 Answers1

0

sum.prototype has nothing to do with the prototype of the function. sum.prototype is the prototype of instances of sum when called as constructor (i.e. with new):

var instance = new sum(); // doesn't make sense, I know
Object.getPrototypeOf(instance) === sum.prototype; // true
instance.add // function

The prototype of sum itself can be accessed via Object.getPrototypeOf(sum) and is Function.prototype.

Object.getPrototypeOf(sum) === Function.prototype; // true

Btw, that's exactly why sum.method() works: You are extending sum's prototype by assigning to Function.prototype.method.


I'm not sure what you are trying to do, but extending functions via their prototype chain is probably not the right solution to your problem.

If you want to add a property to sum, then just assign it directly:

sum.add = function() { ... };
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143