Say I have two functions in JavaScript, and I want to pass the this
pointer from one to the other. I know two ways to do this (shown below). Which one is the best practice?
Option 1:
function a() {
b(this);
}
function b(elem) {
alert(elem);
}
Option 2:
function a() {
b.call(this);
}
function b() {
alert(this);
}
This doesn't answer the question, but the title to the question before it was changed:
What is the difference between function.call(this) and function(this) in JavaScript?
The use of call
sets the context (this
) of the called function:
function foo() {
console.log(this);
}
foo(); // window
foo.call({}); // {}
The default context using non strict mode (In a browser envirement) is window
showed in the example above.
Non strict mode is the default mode. Strict mode is only supported by some browsers.
If the function is a method of an object the context is the object itself:
var obj = {
foo: function () {
console.log(this);
}
};
obj.foo(); // obj
obj.foo.call({}); // {}
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this
There is really no best practice in general, just guidelines. It's strictly depends by the way you're coding. Personally, I would use the first form, it's more functional oriented rather than object oriented, and you avoid an additional operation – changing the contextual object – plus, you will not depends by the context object itself. It means, if you need to reuse b
somewhere, you don't have all the time to change it's contextual object.
I'll give you a practical example. Let's say that b
is a function that set the style.display
of an element
to none
. Let's call it hide
:
function hide(element) {
element.style.display = "none";
}
You can use it like:
hide(document.getElementById("foo"))
So far so good. But what if you want to hide all elements of a list?
// this is used to have an array of element for the example,
// because NodeList are not Array
var slice = Function.call.bind(Array.prototype.slice);
var nodes = slice(document.getElementsByTagName("div"));
nodes.forEach(hide);
You simple have to pass hide
. That's because the callback you pass to forEach
, is called passing as first argument each value of the array.
But it's not over yet. Let's say you want to hide not all the div in the list, but only the div in the list that contains a the text "foo".
function hasFoo(element) {
return element.textContent.indexOf("foo") > -1
}
Then:
nodes.filter(hasFoo).forEach(hide);
And so on. You can really takes advantages of the functional programming aspect and methods of JavaScript, if you decide to pass the "subject" of the function as first argument.
Here you can find the documentation of ES5 methods like filter and forEach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With