Why need bind in setInterval with method function? [duplicate] - javascript

This question already has answers here:
Pass correct "this" context to setTimeout callback?
(6 answers)
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 5 years ago.
Here's working code sample:
function Drum(){
this.noise = 'boom';
this.duration = 1000;
this.goBoom = function(){console.log(this.noise)};
}
var drum = new Drum();
setInterval(drum.goBoom.bind(drum), drum.duration);
If I remove .bind(drum) part from this code instead of 'boom' I'll get 'undefined' in console.
What's the reason of such behavior since typeof drum.goBoom returns 'function' ?

since typeof drum.goBoom returns 'function'
This is actually irrelevant. It's value of this keyword which is important in here. You are passing a function reference by passing drum.goBoom as the first argument of the setInterval function, without using bind for setting the this keyword's value manually the setInterval calls the function with global object as it's this value (context) which doesn't have noise keyword, so console.log logs undefined.

Taking a look at the documentation for bind.
The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
If you omit the bind(drum) then this within the call back will be something other than the drum object you want.

Related

'this' keyword in array prototype function is undefined [duplicate]

This question already has answers here:
ES6 arrow functions not working on the prototype?
(4 answers)
What does "this" refer to in arrow functions in ES6?
(10 answers)
Closed 9 months ago.
I would like to write my own function for every array and I'm using the prototype keyword.
The problem is that when I created the following script:
Array.prototype.test = () => {console.log('length: ',this.length)};
const result = [1,2,3].test();
If I run it in the console of chrome I get the following result:
length: 0
If I run it on my local machine with node script.js I get the following result:
length: undefined
Why is this.length different and why it doesn't reflect the length of the array I'm calling the function on?
That's because you are using the arrow function syntax. The arrow function does not possess a this context, so it "points" to the global context.
The solution is simple:
Array.prototype.test = function() {console.log('length: ', this.length)};
const result = [1,2,3].test(); // length: 3
By adding explicitly function now your context (this) points to the object calling the function.
You are using an arrow function syntax.
When the "this" keyword are being called, it falls back into the global object.
In the browser it falls back into the window object and for this 😉 reason it's return 0 length.
But in the global node object, the length is undefined.
Instead, use the function keyword to get the Array.prototype context.
Array.prototype.test = function(){console.log('length: ',this.length)};

Storing a "apply" or "call" function in a variable - in JS [duplicate]

This question already has answers here:
JavaScript Function Context Incorrect
(3 answers)
Closed 1 year ago.
const j = Object.prototype.valueOf.apply
console.log(typeof j); // "function"
console.log(Object.prototype.valueOf.apply === j); // true
console.log(Object.prototype.valueOf.apply(3)); // WORKS
console.log(j(3)); // ERROR! TypeError: j is not a function
I found something weird situation in JS, about Function.prototype.apply and Function.prototype.call function. Without storing apply function in variable, it works. But when I store apply function to variable, it doesn't work.
What causes this weird situation?
apply expects to be called as a method of a function. (i.e. someFunction.apply(...)). This would make the this value that function.
When you copy apply to j and then call j(); the this value is the default value (typically window if you are running in a browser).
That value is not a function.

Lexical `this` and Timeout [duplicate]

This question already has answers here:
How does the "this" keyword in Javascript act within an object literal? [duplicate]
(4 answers)
Closed 5 years ago.
Im reading through the YDKJS books and I thought I understood lexical this for the most part.
However there is a section with code that shows this:
var obj = {
id: "awesome",
cool: function coolFn() {
console.log( this.id );
}
};
var id = "not awesome";
obj.cool(); // awesome
setTimeout( obj.cool, 100 ); // not awesome
Ok so the first obj.cool() makes sense of course....but why is the setTimeout printing not awesome.....I mean it's still calling obj.cool() which this refers to it's own objects id?
Or does setTimeout get called as another function that calls obj.cool()? but even in that case (Which I tried calling obj.cool() inside another function that also had an id property and it still printed the right one......so why would the this change with setTimeout?
Since the OBJ.COOL function is passed by reference, you are not actually passing the context object with it. The function gets new invocation context and executes on the WINDOW object, which now has a property called ID which was defined earlier.

Why "this" is not working? [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
In java script when we make a new constructor function we use "this.property name". We use "this" to refer the object which currently in use. But in a general function we doesn't use "this" keyword. According to my understanding if we use "this" in function it should point to the current function. However when we used, it was not producing the expected result. Why? Example
function greet(name){ console.log("Hello " + this.name);
}
Output is "Hello" then blank.
Because in general function, we are by default referring 'window' object so anything we make it becomes window level object or variable.
Like,
function fun(){
this.title = "window";
}
fun();
or window.fun(); //both are same. Since we call window.fun, this.title means window.fun.
If you create like this:
var obj = {
}
**Now to make title at obj level, you can do like this:
fun.call(obj);
Now you can call obj.title.**
Read this about this
In most cases, the value of this is determined by how a function is called.
When you use the new keyword in javascript an implicit object is created and returned from the function call. Inside of the function this refers to the newly created object. Calling a function without new does not have the same behavior.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new

Why does passing a JavaScript object's method not update the object? [duplicate]

This question already has answers here:
How does the "this" keyword work, and when should it be used?
(22 answers)
Closed 6 years ago.
I noticed that when passing an object's method (which updates one of the object's own properties) as an argument to another function, the original object will not be modified.
For example:
var obj = {
foo: 0,
bar: function () {
this.foo++;
}
};
function baz(callback) {
callback();
}
baz(obj.bar); // does not alter obj
obj.bar(); // increments obj.foo successfully
console.log(obj.foo); // should be 2, not 1
Why is this, since JavaScript objects are passed by reference?
This is because the context - or this value - of a function is based on how it's called, not on how it's defined. Your bar function doesn't know it's inside the obj object.
When you do obj.bar();, you are calling it in the context of obj, thus this is what you expect.
When you do baz(obj.bar);, you are passing the bar function as a parameter. It no longer has any ties to the obj object. Remember, functions can be treated like variables. So, when baz runs its callback, it's ran in the "global" context (this is window).
The solution here is to use .bind() to "lock in" the this value.
baz(obj.bar.bind(obj));
Because you need to bind the callback to a specific object.
baz(obj.bar.bind(obj));
Functions are only automatically bound to the object before . when you perform the call in the same expression. Simply accessing the property doesn't bind it.

Categories