将函数引用到变量时等于此值的Javascript
是的,这是关于在变量(将函数引用到变量时等于此值的Javascript,javascript,oop,this,Javascript,Oop,This,是的,这是关于在变量(that)中存储this的另一个问题,但我对此感到困惑: function Constructor(){ this.key = 'my key' }; Constructor.prototype.start = function(){ var that = this; return (function (){ console.log(that.key) }()); }; foo = new Constructor; f
that
)中存储this
的另一个问题,但我对此感到困惑:
function Constructor(){
this.key = 'my key'
};
Constructor.prototype.start = function(){
var that = this;
return (function (){
console.log(that.key)
}());
};
foo = new Constructor;
foo.start()
bar = new Constructor;
newFoo = bar.start
newFoo()
我想既然这个
存储为一个变量,我就可以在不失去作用域的情况下传递start()
方法了?
我知道人们经常讨论这个问题,但我找不到一个适合这种具体情况的答案
如果不使用构造函数,如何才能在newFoo()
中恢复作用域。应用(此)
多谢各位
我想既然它存储为一个变量,我就可以在不失去作用域的情况下传递start()方法了
不,因为您仍然在使用this
的值,就像调用start
时一样,只是间接地使用。您可以在构造函数中执行此操作:
function Constructor() {
// ...other stuff...
var that = this;
this.start = function(){
console.log(that.key)
};
// ...other stuff...
}
(…并移除您在原型上放置的一个)
现在你可以随意传递start
that
将是调用构造函数时this的值start
持久引用了调用构造函数得到的变量
当然,代价是通过Constructor
创建的每个实例都有自己的start
函数副本。大多数现代JavaScript引擎都足够聪明,可以重用函数的代码(但它们需要为每个start
创建单独的函数实例,它们只能重用幕后的实际代码)
您的另一个选择不是在构造函数
或开始
中处理此问题,而是在您将开始
的副本发送到别处时,使用函数#bind
处理此问题<代码>函数#绑定
是ECMAScript 5(ES5)的一项功能,但它可以在较旧的引擎上填充
例如:
// Nice boring constructor with `start` on the prototype
// Note I've made the key an argument; in your code, all of them had the same key
function Constructor(key) {
this.key = key;
}
Constructor.prototype.start = function() {
console.log(this.key);
};
// **********
// Using it
var c1 = new Constructor("c1");
// Use it normally
c1.start(); // "c1" as you'd expect
// Use it forgetting that `this` will change
setTimeout(c1.start, 0); // "undefined" - doh!
// Use it via Function#bind
setTimeout(c1.start.bind(c1), 0); // "c1"
更多(在我的博客上):
newFoo.apply(bar)
传递适当的作用域。您能提供一个您期望的输出的示例吗?T.J.的答案是正确的,如果这是你试图解决的问题,请告诉我你为什么否决这个?这是一个合理的问题,那么有什么错呢?谢谢,但是在start()方法中是否也有实现这一点的方法,或者我真的需要为此使用构造函数?如果是这样的话,那没问题,只是为了testing@ChristophHa:如果在原型上放置start
,则无法将this
的值保存在that
中,因为此时您没有访问该值的权限。它在Constructor
中工作的原因是,此时,您可以访问希望具有的值。当然,你的另一个选择是使用函数#bind
如果/当你分发start
时,我会补充这一点。啊,是的,还没有看到这个,真的很好的解释,期待你的博客:)