Reputation: 3698
I am learning bind
, call
and apply
functions. I am using bind to set callback for the api calls. Here are my functions:
function errorCallback(list, error) {
$log.error('Somehting went wrong while loading json.');
$log.log(list, error);
}
function successCallback(list, response) {
$log.info('JSON loaded successfully.');
//$log.log(list, response);
//this works
//$scope.list = list.concat(response.data);
//this doesn't
list = list.concat(response.data);
$log.log($scope.list, list);
}
This is how I am binding them:
var successCb = successCallback.bind(null, $scope.list),
errorCb = errorCallback.bind(null, $scope.list);
When I use them as callback:
$scope.loadJson = function() {
$http.get('data.json').then(successCb, errorCb);
};
They are getting invoked properly. But the concern is that when I update list
, it does not update the actual parameter which is passed. I want to know that when we bind the parameters for bind, are they bound using value or reference? Here's the plunkr.
Upvotes: 0
Views: 58
Reputation: 23642
Function.prototype.bind
does the same thing as call or apply, but does not call the function right away instead it returns a new function with your parameters bound to this and when the function is called from a new scope or context, it will remain same.
Binding also allows you to prevent your constructors from being "hacked" by apply
or call
since it will always use the binded parameters for this no matter what someone sends to attempt to override this via call
or apply
.
If you have noted, the last one does not change from guest
to rajini
even though we try to override
it via call
.
function Profile(u) {
this.user = u;
this.getUser = function () {
return this.user;
};
}
var x = new Profile('guest');
alert(x.getUser.apply({
user: 'Vinoth'
})); // Vinoth
alert(x.getUser.call({
user: 'Google'
})); // Google
alert(x.getUser.bind(x).call({
user: 'Rajini'
})); // guest
A fiddle to play around. https://jsfiddle.net/5qxpn4v0/
Upvotes: 1
Reputation: 665286
Everything in JavaScript is passed by value. Some of these values can be references to mutable things (objects - also called reference values), but that's it. When you reassign to list
, nothing is changing but the list
variable in your local scope. You actually would need to mutate your array, which concat
doesn't do - use push
instead.
If you want to mutate the $scope
, you will need to pass it itself and explicitly assign its .list
property.
Upvotes: 4