1

What is the purpose of call and apply methods in the language?

It seems to be an example of anti-pattern which breaks OOP principles. Or it just presents multi-paradigm approach?

This example made me to ask this question.

In one place of application (a part of library) there is such a code

socket.emit = function() {
    if (!socket.banned) {
      emit.apply(socket, arguments)
    }
 }

In another part of application (self written) there is such piece of code

socket.emit = function(arguments){
    data = Array.prototype.slice.call(arguments);
    emit.apply(socket, data);
}

In the first place the object should not work if it is banned. But the second part knows nothing about library logic and works independently.

How this situations may be resolved? We use libraries to ease the most difficult parts.

2
  • 2
    The purpose is to invoke a function with a specific calling context, the this, and any number of arguments. Other than that, it's not really clear what you need to know. If this is a question about programming principles, maybe this is better suited for Software Engineering. Commented Oct 11, 2017 at 20:40
  • In your second case, why did you choose the name arguments for your formal parameter? Doing so shadows the arguments object, since the identifier arguments now refers to the first argument of the function, instead of the default object called arguments that has access to all arguments passed into the function. Do you expect emit to be called with an array-like object as its first parameter? If you did emit = function(firstArg){ ... and slice.call(firstArg); the functionality would be much clearer. Commented Oct 11, 2017 at 20:47

1 Answer 1

3

Function.prototype.call exists for one purpose only, and this is to allow the function to be called with a specific value of this, i.e. the one that's passed as the first parameter.

Function.prototype.apply is the same, but with the added advantage that the array passed as the second parameter is split out into multiple parameters when the function is invoked. This is useful when you want to call a function that takes a variable sized list of arguments but you have those arguments ready in an array instead of as individual values.

Take, for example, Math.max. If I have a set of unknown size and I wish to find the largest there are two approaches:

  1. successively compare each element against the current maximum until you find the largest

  2. pass all of them directly to Math.max.

I can't call Math.max(a, b, c, etc) because I don't know how many variables there are. Instead I can call Math.max.apply(null, myArray) and that gets expanded to Math.max(myArray[0], myArray[1], etc).

NB1: in ES6 .apply isn't strictly required any more because you can use .call with the ... spread operator, e.g. Math.max.call(null, ...myArray).

NB2: this has nothing to do with breaking OOP principles.

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

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.