Call, Bind, Apply Vs Passing The Reference Object As An Argument - javascript

Using call and bind is important when setting the value of this to the intended object. But what is the significance of using this instead of just passing the object as an argument to the function?
The question occured to me after seeing that .bind is not supported in IE9 and below, so I started passing the object as a parameter to the function I am calling. (I know I could use a shim for bind but that is not the question. The question is about the rationale behind using this.)
What is the purpose of the this, call, apply, bind syntax in Javascript and what was it a solution to? Wouldn't it be simpler to pass the object as a parameter both for cross-browser support and simplicity (since this is commonly misunderstood or forgotton to be set correctly in code)?

As far as I know, this technique used at some languages (like Delphi). But using one-argument-less is more convenient I guess. It is not a functional style, it is OOP style and we love it, right? :)

Related

Is there a case where using bind would not cover the need for using either call or apply?

I am learning javascript via javascript.info.
I learned about bind (and a lesson before about call and apply)
I see this post inquires about the differences on all 3.
After reading all that, I wonder: is there a scenario where using bind would NOT cover the need for using either call or apply ?
I mean, call or apply are meant for calling the function immediately. bind - later on.
Would not the following work in all cases?
let f = function(){/* code here */};
let errorFreeF = f.bind(myContextObj);
errorFreeF();
A less verbose snippet:
function(){/* code here */}.bind(myContextObj)();
If the answer is using bind is always safe and indeed covers all scenarios, seems like the call/apply could be deprecated in future JS versions ? Or it performs worse?
You can use .bind as a substitute for .call and .apply. If you wanted, you could convert all uses of .call and .apply with .bind.
The other combinations are true as well. If you really wanted to, you could also replace all instances of those methods with .call, or with .apply.
It's just that it's sometimes inelegant to do so. For similar reasons, even though Array.prototype.forEach could be used to identify an element which matches a condition in an array, Array.prototype.find is more appropriate and requires less code.
seems like the call/apply could be deprecated in future JS versions ?
No, for a few reasons:
They're useful methods to have (they can result in cleaner code than having to write the same thing with .bind)
Using .bind creates a function. In rare cases, the extra overhead resulting from the creation of a function may be a problem. (But .call and .apply only invoke functions, they don't create functions)
The language designers will never implement a change (such as removing .call or .apply) because that will break existing websites, which is avoided at all costs.

overloading vs overriding in javascript

In a recent JavaScript interview I was asked about overloading vs overriding. I know this is a concept in Java. But is there something similar in JavaScript, and if so what would be code examples? My understanding is that overloading isn't common in javascript. Why would you need to use "overloading" in JS?
OverRiding is a bit clearer to me - an example of over riding would be in subclassing where you are inheriting from a super class but over riding some methods/properties to create unique ones for a sub class.
JavaScript does not support overloading.
JavaScript supports overriding, so if you define two functions with the same name, the last one defined will override the previously defined version and every time a call will be made to the function, the last defined one will get executed.
more read here http://blog.mastykarz.nl/overloading-functions-javascript/
There's a nice example of 'faking' JavaScript function overloading here: https://stackoverflow.com/a/457589/2754135
You basically use a parameter in your function that takes an object, that object contains any number of parameters you want.
It's not actually overloading obviously, cause that's not possible in JavaScript.
there is no need for the traditional concept of overload in javascript, because of its dynamic nature. In the more traditional programming languages, as Java, you can define a method multiple times with different signatures and the language will correctly use the method you want to call just using the signature: thats called overload of methods. On the other hand override is the possibility to redefine a method of the parent class in the child class.
To do overload in javascript it is common practice to use last parameter that is called options. For example
function yourFunction(firstParam, secondParam, options) {};
the options is just a javascript object that have props you want to pass. Then you can use the so called "options" pattern to check for props.
To do override it is more difficult in pure javascript because of the prototypal nature of the language: when you "extend" a base object with a new one, you can use .call() function of the constructor object passing this to decorate the newly created object with the parent props.
While JavaScript does not support overloading in a traditional sense,
More than the required arguments may be passed at any time to a JavaScript method, and accessed through the arguments variable. This is functionally similar.

using .call vs. passing "this" in JavaScript

I know that if you have some javascript function and you want to call it such that using this within it would refer not to the object on which it was directly called you can use func.call(thatObject,param,and,more,params...).
But suppose you are the writer of func and the only usage for func is via func.call,
Why would you not define it to begin with as:
function func(that,param,and,more,params...) {
//and in here use *that* and not *this*
}
yep, it looks less "cool" because its not a method of an object,
but hey if the only usage for func is via func.call it all seems like just extra code and overhead.
Am I missing something here? or is the source code in which I have seen this pattern just "over OOed" ?
There appears to be a large performance difference. Using
func(){
//code here, this.something
}
func.call(thatObject)
according to the first couple of tests is about 8 times slower than using
func(that){
//code here, that.something
}
func(thatObject)
Test it yourself, JSPerf here
Ultimately though, speed alone is rarely the most important factor in which code we use. Code is designed for people as much as it is for computers, we need to communicate our intentions clearly to both. Whichever makes the code cleanest is best, and we should follow conventions whenever it is feasible. I personally prefer the second option here, but I think the general convention is the first. So I think you use call in most situations, except for when you need the fastest code possible or if the convention changes.
Your pattern will work in this scenario but in general it has some problems ...
Constructor functions -> We create objects by using new keyword where 'this' object is automatically created and returned (default) also has the link with the function's prototype.
When calling the function someone might forget to pass 'that' object and your code will fail. In case of call if you pass null it is reset to global object (non-strict mode which is common)
func.call is intended to be used when an alternative (or any) context for the function is needed to be provided.
Your suggestion is odd, since, when you define the function using this pattern:**
function func(that,param,and,more,params...) {
//and in here use *that* and not *this*
}
it's either:
doesn't belong to any object
in which case passing an object to act as this doesn't make any sense, since there should be no this.someThing calls to begin with
or belongs to a different object or is defined to be a plug to an object
in which case it does exactly what func.call would do, while contaminating the definition of the function with redundant parameter.
UPDATE:
Think of the second example in this way - imagine that some set of Objects (what you'd call from the same "class") allow injection of arbitraty functions, say for iteration over all properties of the object and some summary or manipulation or what have you.
In Java, the common pattern is to create an Iterator and pass it, and its main purpose is to serve as sort of placeholder so that next and hasNext methods can be called - since Java doesn't really have object-less functions. (granted there is some additional logic there, but let's leave it alone for the sake of this discussion).
JavaScript does not neeed this! All these call and apply methods do not need to have some additional Iterator object to hold them. They can be defined "detached" from any object, while still with intention to be used in a context of one (hence this usage in their code) and injected into code that knows to accept such functions.
The "host" code than only needs to call or apply them, knowing that this will refer to itself - this very "host" object.
This leads to a more concise, reusable and portable code, IMO.
UPDATE 2:
See more here.

What is the difference between $.proxy() and bind()?

In 2009, ECMAScript 5 added a built-in bind() function which takes an object as a parameter and returns an identical function in which this will always refer to the object you passed it. (I couldn't find anything that looked like a canonical documentation link.)
How is this different from jQuery's $.proxy() function? Did $.proxy() come first before ECMAScript 5 was released? Is there a particular reason to favor $.proxy(function(){}, this) over function(){}.bind(this)?
proxy came first and you should likely favor bind as it is a standard. The way they are called varies slightly (due to being attached to Function.prototype vs just being a function) but their behavior is the same.
There is a pretty good post here: jQuery.proxy() usage, that ends with that advice.
Edit
Please pay no attention to this post (despite being the accepted answer).
Long story short, it was my own fault for making assumptions about the context of the question, rather than just looking up the API docs, and was accepted as the answer before I could realize my own stupidity (making assumptions, without validating them) and delete it.
Matt Whipple's answer is 100% correct, and while I disagree with his statement that real Proxies are useless in JS (they would be fantastic in some low-level concerns), the rest of his statements are flat-out objectively correct (aside from actual dates for .bind vs .proxy, as .bind was in the spec years before it landed consistently in browsers).
Below is my shame, in the stocks for all to see...
Feel free to throw tomatoes at it.
If you want to know why I answered the way I did, read the comments below.
The difference between $({}).proxy() and func.bind({}) is that proxy is a loose connection.
You can detach at any time.
That's sort of what proxies are for.
The invisible-interface between what you want to do and the thing that will actually do it.
For the record, there's also a $.bind() which is not a proxy. That is to say, it fully binds to this, in the same way that func.bind() does, rather than implementing a mediator-system to attach and detach context from functions at-will.
$.proxy came first.
Below is a simple way to preserve a particular context on function call
var myProxy = (function(context,fn){
return function(){
fn.call(context);
}
})( myContext, myFn );
You could easily use this before it came out jquery.
Answer is simple:
bind is the official.
Use bind - if it really is supported in browsers which is required to run the script
From Underscore bind vs jQuery.proxy vs Native bind
In addition to what is already mentioned, there's another difference between $.proxy() and .bind. Methods bound with $.proxy will return the same reference if called multiple times; jQuery caches functions proxied to an Object.
jsFiddle
Here is a test you could try to for performance comparison.
http://jsperf.com/bind-vs-jquery-proxy/5
At this time, October 2014.
The performance varies like crazy between browsers.
IE 11 native bind is fastest.
However, for all three browsers I tested with, native bind out preform jquery proxy.
And since bind() is standard, I would suggest sticking to it if possible.

When do you use _.bind vs _.bindAll?

I noticed there is _.bind and _.bindAll in Underscore. I was wondering when do you use one over the other? What if you have multiple this that you need to bind, which one would you use?
Well they do similar but quite different things. The _.bind() function is for binding a single function to an object, while _.bindAll() is about binding some or all of the function-valued properties of an object to the object.
Thus _.bind() is useful when you've got any situation that requires a function be invoked with a fixed receiver, and _.bindAll() is useful when you're working with more "objecty" code. That is the case when you've got objects with properties that are functions, and these functions expect (require) that they be invoked with the object as the receiver so that they can access other functions.
The examples in the Underscore documentation explain further.
Note that modern JavaScript runtime environments have a .bind() method on the Function prototype, which (seems to me) should be preferred over _.bind().
edit — As to your questions about having to create bound functions for multiple objects, the answer is that neither of _.bind() and _.bindAll() addresses that. You simply have to iterate somehow and collect the bound functions in some appropriate way.

Categories

Resources