访问此内容的更好方法是什么。 Function.bind vs 捕获变量
What is better way to access this. Function.bind vs capturing variables
这是一个基本问题,但这是一个有趣的问题。
例如,
var Foobar = function(){
this.baz = 100;
this.timer = null;
this.printLazy = function(){
this.timer = setTimeout(function(){
console.log(this.baz); //correctly bind this.
}.bind(this), 1000);
}
}
创建一个传统的 class,我们可以创建实例并将 printLazy
称为
var myBar = new Foobar();
myBar.printLazy();
现在在上面的代码中,printLazy
方法设置了一个计时器并在其中访问 this
.
同样的事情可以使用捕获来实现,
this.printLazy = function(){
var self = this; //capture this.
this.timer = setTimeout(function(){
console.log(self.baz); //correctly bind this.
}, 1000);
}
- 这些方法中有一个比另一个更好吗? (考虑效率还是性能)
- 第二个方法是否会导致内存泄漏,如果它被快速连续调用 1000 次或更多次,其中 self 将被函数内的其他部分引用?
Is one of these methods are better than the other? (Considering efficiency or performance)
不是真的。在您的 specific 示例中,使用 bind
的版本创建了一个不必要的函数对象(但是 JavaScript 引擎 非常这样做)。但这也意味着您传递的函数 setTimeout
不会关闭任何东西,这是 JavaScript 引擎可能能够用来优化附加到它的上下文的信息(“闭包优化” ).
但在现代环境中,您可能会在那种情况下使用箭头函数而不是 self
选项:
this.printLazy = function(){
this.timer = setTimeout(() => {
console.log(this.baz);
}, 1000);
}
这将在计时器触发时记录 this.baz
。根据您需要记录的内容,另一个选项是 setTimeout(console.log, 1000, this.baz)
。不同之处在于,此版本将在计时器 设置 时记录 this.baz
的值,而不是它 触发 时的值。 (它还依赖于 console.log
,在大多数 [但可能不是所有] 环境中,并不关心 this
是什么,当你调用它时。)这是因为 setTimeout
通过任何当它调用它时,你给它的额外参数给它调用的函数。
Can 2nd method can cause memory leaks, if its called lets say 1000 or more times in a quick succession where self would be referenced by other parts inside the function?
没有。内存泄漏不是由于快速执行操作引起的。它们是由于您不再需要内存而不释放内存而导致的。你正在做的不是那个。
最近遇到了同样的问题(在 React 中),发现 this article 显示了几个选项。以下是 3 个适合您的情况,最后一个是推荐选项。
选项 1
使用箭头函数。但是,这仍然会在每次调用 printLazy
时创建一个新函数。
this.printLazy = function(){
this.timer = setTimeout(() => {
console.log(this.baz); //correctly bind this.
}, 1000);
}
选项 2
创建第二个函数并将其绑定到构造函数中,这仍然存在性能缺陷。
var Foobar = function(){
constructor() {
this.printLazyCallback = this.printLazyCallback.bind(this)
}
printLazyCallback() {
console.log(this.baz); //correctly bind this.
}
}
选项 3(您应该使用的选项)
创建第二个函数作为 class prop arrow function
var Foobar = function(){
printLazyCallback = () => {
console.log(this.baz); //correctly bind this.
}
}
这是一个基本问题,但这是一个有趣的问题。 例如,
var Foobar = function(){
this.baz = 100;
this.timer = null;
this.printLazy = function(){
this.timer = setTimeout(function(){
console.log(this.baz); //correctly bind this.
}.bind(this), 1000);
}
}
创建一个传统的 class,我们可以创建实例并将 printLazy
称为
var myBar = new Foobar();
myBar.printLazy();
现在在上面的代码中,printLazy
方法设置了一个计时器并在其中访问 this
.
同样的事情可以使用捕获来实现,
this.printLazy = function(){
var self = this; //capture this.
this.timer = setTimeout(function(){
console.log(self.baz); //correctly bind this.
}, 1000);
}
- 这些方法中有一个比另一个更好吗? (考虑效率还是性能)
- 第二个方法是否会导致内存泄漏,如果它被快速连续调用 1000 次或更多次,其中 self 将被函数内的其他部分引用?
Is one of these methods are better than the other? (Considering efficiency or performance)
不是真的。在您的 specific 示例中,使用 bind
的版本创建了一个不必要的函数对象(但是 JavaScript 引擎 非常这样做)。但这也意味着您传递的函数 setTimeout
不会关闭任何东西,这是 JavaScript 引擎可能能够用来优化附加到它的上下文的信息(“闭包优化” ).
但在现代环境中,您可能会在那种情况下使用箭头函数而不是 self
选项:
this.printLazy = function(){
this.timer = setTimeout(() => {
console.log(this.baz);
}, 1000);
}
这将在计时器触发时记录 this.baz
。根据您需要记录的内容,另一个选项是 setTimeout(console.log, 1000, this.baz)
。不同之处在于,此版本将在计时器 设置 时记录 this.baz
的值,而不是它 触发 时的值。 (它还依赖于 console.log
,在大多数 [但可能不是所有] 环境中,并不关心 this
是什么,当你调用它时。)这是因为 setTimeout
通过任何当它调用它时,你给它的额外参数给它调用的函数。
Can 2nd method can cause memory leaks, if its called lets say 1000 or more times in a quick succession where self would be referenced by other parts inside the function?
没有。内存泄漏不是由于快速执行操作引起的。它们是由于您不再需要内存而不释放内存而导致的。你正在做的不是那个。
最近遇到了同样的问题(在 React 中),发现 this article 显示了几个选项。以下是 3 个适合您的情况,最后一个是推荐选项。
选项 1
使用箭头函数。但是,这仍然会在每次调用 printLazy
时创建一个新函数。
this.printLazy = function(){
this.timer = setTimeout(() => {
console.log(this.baz); //correctly bind this.
}, 1000);
}
选项 2
创建第二个函数并将其绑定到构造函数中,这仍然存在性能缺陷。
var Foobar = function(){
constructor() {
this.printLazyCallback = this.printLazyCallback.bind(this)
}
printLazyCallback() {
console.log(this.baz); //correctly bind this.
}
}
选项 3(您应该使用的选项)
创建第二个函数作为 class prop arrow function
var Foobar = function(){
printLazyCallback = () => {
console.log(this.baz); //correctly bind this.
}
}