Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js: can't call one Javascript prototype method from another?

I'm trying to define a class with two public methods. It so happens that one of the methods is useful for implementing the other one, but for the life of me, I cannot get that function to be recognized within the scope of the other one. I have no idea whether this is something specific to node.js or not, but in case it matters, this is running under node.

Here is a short toy problem which reproduces the behavior I'm seeing:

function Foo() {
    this.list = [];
}

Foo.prototype = {
    addSeveral: function(arr) { arr.forEach(function(v) { addOne(v)} ) },
    addOne: function(item) { list.push(item); }
}

f = new Foo();
f.addSeveral([1,2,3]);

When I run this, it blows up with:

[jasonb@localhost]$ node testobj.js

/home/jasonb/work/testobj.js:6
Foo.prototype.addSeveral = function(arr) { arr.forEach(function(v) { addOne(v)}
                                                                     ^
ReferenceError: addOne is not defined
    at /home/jasonb/work/entity_mapping/testobj.js:6:70

I've tried every variation I can find on how to assign stuff to a class's prototype, with the same results. And if I try to call this.addOne(v) instead, it still blows up, but with TypeError: Object #<Object> has no method 'addOne'

How can I call addOne() within addSeveral()?

like image 766
Jason Black Avatar asked Dec 20 '25 05:12

Jason Black


1 Answers

Because forEach invokes a callback function for each element of the array, you're losing context (this is not the Foo object inside your callback). You can close over a reference:

Foo.prototype = {
    addSeveral: function(arr) { var self=this; arr.forEach(function(v) { self.addOne(v)} ) },
    addOne: function(item) { this.list.push(item); }
}

...or just use a regular loop, which will have much better performance – function invocation is expensive.

addSeveral: function(arr) { for(var i = 0; i < arr.length; i++) this.addOne(arr[i]); };
like image 155
josh3736 Avatar answered Dec 22 '25 20:12

josh3736



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!