0

What is the proper way to create a function that updates an object's fields? The way below, nothing seems to happen:

function adjmatrix(neighbors){
    this.neighbors = neighbors
    this.sum = 0
}

adjmatrix.prototype.update = function(){
    this.neighbors.forEach(function(a){a.sum += 10})
}

var myMatrix = new adjmatrix([1,2,3])
myMatrix.update()
print(myMatrix.sum) //Expect a value of 30, I get 0.

Kind of new to Javascript, so I'm not too clear on how scoping and stuff works. Thanks for your help. I am running my programming through d8 in the command line.

goodcow
  • 3,465
  • 3
  • 28
  • 46

3 Answers3

2

In order to update the "sum" property of the object, your "update" method should look like this:

adjmatrix.prototype.update = function(){
    var matrix = this;
    this.neighbors.forEach(function(a){matrix.sum += 10})
}

If you wanted to sum up the "neighbors" values, it'd look like this:

adjmatrix.prototype.update = function(){
    var matrix = this;
    this.neighbors.forEach(function(a){ matrix.sum += a; })
}

The .forEach() call passes in each of the values of the array, one per call to the function.

Pointy
  • 371,531
  • 55
  • 528
  • 584
  • Could you explain why I need to do `var matrix = this;`? Doesn't `this` refer to the function? – goodcow Jun 26 '14 at 16:08
  • @goodcow no, `this` does not refer to the any function in this case. The details of how `this` works are somewhat involved, but here basically it's necessary to save the value of `this` as it stands when the "update" function is called, so that inside that little callback function the code can operate on the proper object. – Pointy Jun 26 '14 at 16:10
  • 1
    @goodcow [here is a good Stackoverflow question on the subject of `this` and how it gets its values](http://stackoverflow.com/questions/3127429/javascript-this-keyword) – Pointy Jun 26 '14 at 16:12
  • Why can't I do this.sum += 10? Why do I have to declare var self = this? – goodcow Jun 26 '14 at 16:36
  • 1
    @goodcow Because `this` gets a value upon each function call, based on how that function call is made. You can write `this.sum`, but the value of `this` will not be the same as the value of `this` in the outer context of the "update" function. Read that other question; this is a fundamental aspect of JavaScript semantics. – Pointy Jun 26 '14 at 16:40
1

The code you have right now:

adjmatrix.prototype.update = function(){
    this.neighbors.forEach(function(a){a.sum += 10})
}

Tries to update the sum property of each element of the neighbors array, which means that it's trying to update the sum property of the numbers 1, 2, and 3. This won't work since they don't have a sum property. Change your code to this:

adjmatrix.prototype.update = function(){
    var self = this;
    this.neighbors.forEach(function(a){ self.sum += 10; })
}
Vivin Paliath
  • 87,975
  • 37
  • 202
  • 284
1

ES5 reduce method to avoid touching this.sum in every loop calls

adjmatrix.prototype.update = function(){
    this.sum = this.neighbors.reduce(function(memo, current) {
        return memo + current;
    }, 0);
}
Krzysztof Safjanowski
  • 6,651
  • 3
  • 30
  • 44