wberry
wberry

Reputation: 19367

JavaScript: using reference to "method" changes behavior

JavaScript functional programming question. Here is a screen-scrape of my node REPL session. Why does my y(4) call not push into the x array? Is there a simpler way than the function near the bottom to do the same thing?

> var x = []
undefined
> var y = x.push
undefined
> x.push(3)
1
> y(4)
2
> x
[ 3 ]
> y.call(4)
undefined
> x
[ 3 ]
> (function(data){x.push(data);})(4)  # too much typing :-)
undefined
> x
[ 3, 4 ]

Please forgive if this is a duplicate question; it's not clear to me how to search for this kind of thing.

Upvotes: 1

Views: 80

Answers (1)

bfavaretto
bfavaretto

Reputation: 71938

The first parameter to .call is the this context to be used inside the function. I believe it will work if you use this instead:

y.call(x, 4)

When you don't set this properly, you are not acting on x. When you create a reference y to x.push, that reference is not bound to x. If you want a bound version of push, you can use var y = x.push.bind(x) as suggested by @go-oleg (or Array.prototype.push.bind(x)). Then y(4) will push to x.


Now, the problem with Array.prototype.push is that it relies on this, being more suited for an object-oriented programming style. A more functional approach, I believe, would be something like the following (illustrated with the underscore library):

function push(arr) {
   return arr.push.apply(arr, _.rest(arguments));
}

var x = [];
var pushToX = _.partial(push, x);

pushToX('foo', 'bar');
console.log(x); // ['foo', 'bar']

http://jsfiddle.net/hUJjz/

Upvotes: 4

Related Questions