0

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.

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Everything in JavaScript is passed by value ??. I think objects are passed by reference
@murli2308: That's why I stated it so explicitly - because so many don't believe it. Objects are reference values that are still passed by value. The parameter variable does contain a reference (value) to the object, it's not a reference to the "passed variable". Assigning to the variable list only changes that variable, no matter whether it contained an object (array) or not.
@Bergi makes sense. Thank you very much
1

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/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.