[英]Settimeout, bind and this
Here I have copied code snippet from MDN : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind这里我从 MDN 复制了代码片段: https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
};
LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
};
var flower = new LateBloomer();
flower.bloom();
// after 1 second, triggers the 'declare' method
The most confusing part is : window.setTimeout(this.declare.bind(this), 1000);
最令人困惑的部分是: window.setTimeout(this.declare.bind(this), 1000);
I understand how this
works and this
inside settimeout is always bound to global object.I know there can be var self or var that inside bloom function.我了解this
是如何工作的,并且 settimeout 内部的this
始终绑定到全局对象。我知道bloom函数内部可以有var self或var 。
There are two this
in that line but which this
refers to what and how that works is totally confusing.该行中有两个this
,但是this
指的是什么以及如何工作,这完全令人困惑。
How works?如何运作?
First of all read this article , which offers a very nice explanation about how this
works.首先,阅读这篇文章,它提供了有关如何一个很好的解释this
作品。
.bind(this, args)
just helps you to pass your this
context inside your function (because inside it in your example by default this
is undefined
or refers to window
). .bind(this, args)
只是帮助您将this
上下文传递到您的函数中(因为在您的示例中,默认情况下this
是undefined
或指的是window
)。
Also bind
is a nice alternative to this:另外bind
是一个很好的替代方案:
// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
var self = this;
window.setTimeout(self.declare, 1000);
};
And as the last point in es6
you can do it in this way:作为es6
的最后一点,你可以这样做:
window.setTimeout(() => {
//do some stuff
}, 1000);
instead of而不是
window.setTimeout(function () {
//do some stuff
}.bind(this), 1000);
this allow you to not think about this
.这让你不用考虑this
。
MSDN defines Function.prototype.bind()
as, MSDN 将Function.prototype.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. bind() 方法创建一个新函数,在调用该函数时,将其 this 关键字设置为提供的值,并在调用新函数时在任何提供的参数之前提供给定的参数序列。
By using .bind(this)
we are passing this
to the function declare
通过使用.bind(this)
我们将this
传递给函数declare
See this snippet.看到这个片段。
function LateBloomer() { console.log(this.constructor); this.petalCount = Math.ceil(Math.random() * 12) + 1; } // Declare bloom after a delay of 1 second LateBloomer.prototype.bloom = function() { window.setTimeout(this.declare.bind(this), 1000); }; LateBloomer.prototype.undefinedbloom = function() { window.setTimeout(this.declare, 1000); }; LateBloomer.prototype.declare = function() { console.log(this.constructor); console.log('I am a beautiful flower with ' + this.petalCount + ' petals!'); }; var flower = new LateBloomer(); flower.bloom(); flower.undefinedbloom();
In the function undefinedbloom
we are just calling the declare function.在undefinedbloom
函数中,我们只是调用了声明函数。 So the object will be the window
object.所以对象将是window
对象。 It doesn't have property petalCount
so its undefined.它没有属性petalCount
所以它未定义。
In the function bloom
we are binding the this
of LateBloomer
to the declare function by which we will have access to the LateBloomer
's object petalCount
.在函数bloom
我们将LateBloomer
的this
LateBloomer
到declare 函数,通过它我们可以访问LateBloomer
的对象petalCount
。
this
in JavaScript is a very difficult to fathom at first. JavaScript 中的this
一开始很难理解。
MDN Link: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this MDN 链接: https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/this
function LateBloomer() {
this.name = 'triven'; //simplified property
}
// Some thoughts we discuss main requirement.
LateBloomer.prototype.bloom = function() {
window.setTimeout(function() {console.log(this);}, 1000); //Logs window: We all know that keyword this INSIDE CALLBACK
//function refers to Window [Comment 1]
//window.setTimeout(console.log(this), 1000); /Attentions: Here it is very easy to MISUNDERSTAND
//that keyword this is inside setTimeout and it should refer to window.
//Please note that here keyword this is not INSIDE CALLBACK function so here
//keyword this will refer to object on which its wrapper function is
//executed(in our case flower). [Comment 2]
};
//The requirement: We need to call .bloom and it should log name after 1 second.
LateBloomer.prototype.bloom = function() {
//here keyword this refers to object
//window.setTimeout(function() {console.log(this);}, 1000); //But inside callback keyword this refers to window.
};
//We need some way to access object inside call back function so that its name can be accessed after 1 sec.
//step 1; Taking out anonymous function and adding it as a prototype property
LateBloomer.prototype.bloom = function() {
//window.setTimeout(this.callback, 1000); //Note: Keyword this is not inside callback so
//it is referring to object (not window). We can access newly
//defined function on the object. Also keyword this placed inside callback
//function(below) will still refer to window.
};
LateBloomer.prototype.callback = function() {console.log(this.name);}
//step 2; bringing .bind into picture.
//Definition of .bind as per MDN : The bind() method creates a new function
//that, when called, has its this keyword set to the provided value
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.callback.bind(this), 1000); // Okay now we are now invoking .callback method on the object and
//passing the same object to bind.
// The keyword this inside newly return function (as a result of bind) will now refer to object
// we passed as argument to bind and we should not be able to access name property of our object.
// Note : Here both this keywords refers to same object ie on which which are calling .bloom.
//Note : we are no longer using passing callback function defined below. Instead we are now passing
// and exact copy of it but configuring it in such a way that keyword this start refering to object we passed.
};
LateBloomer.prototype.callback = function() {console.log(this.name);}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.