OO JavaScript-避免self=this
当以面向对象的方式使用JavaScript时,有没有人知道如何避免声明var self=this?我经常看到它,我很好奇它是否只是你必须做的事情,或者是否真的有一种方法(也许是类库?)让你绕过它?我知道为什么有必要(这有功能范围)。但是你永远不知道外面会有什么聪明的方法 例如,我通常在JS中编写我的“类”:OO JavaScript-避免self=this,javascript,Javascript,当以面向对象的方式使用JavaScript时,有没有人知道如何避免声明var self=this?我经常看到它,我很好奇它是否只是你必须做的事情,或者是否真的有一种方法(也许是类库?)让你绕过它?我知道为什么有必要(这有功能范围)。但是你永远不知道外面会有什么聪明的方法 例如,我通常在JS中编写我的“类”: function MyClass() { } MyClass.prototype = { firstFunction: function() { var se
function MyClass() {
}
MyClass.prototype = {
firstFunction: function() {
var self = this;
$.ajax({
...
success: function() {
self.someFunctionCall();
}
});
},
secondFunction: function() {
var self = this;
window.setTimeout(function() {
self.someOtherFunction();
}, 1000);
}
};
不,如果要在不同的上下文(如回调)中引用
此
,则需要执行此操作,否则它将被重新分配给另一个对象,如窗口
顺便说一句,
self
是一种python约定——在JavaScript中,人们通常使用的约定是this
。但这只是个人品味的问题。在您的第一个功能中,您可以这样做
$.ajax({
context: this,
success: function() {
this.someFunctionCall();
}
});
window.setTimeout($.proxy(function() {
this.someOtherFunction();
}, this), 1000);
在第二种情况下,您可以这样做,尽管您需要在较旧的浏览器中填充
window.setTimeout(function() {
this.someOtherFunction();
}.bind(this), 1000);
使用jQuery,您也可以这样做
$.ajax({
context: this,
success: function() {
this.someFunctionCall();
}
});
window.setTimeout($.proxy(function() {
this.someOtherFunction();
}, this), 1000);
一些javascript框架有自己的事件处理机制,允许您为处理程序函数设置上下文。通过这种方式,您可以简单地将
This
指定为上下文,而不是使用self=This
我想到的另一种可能性是在全球范围内的某个地方传递上下文。像
function MyClass() {
MyClass.instances.push(this);
}
MyClass.instances = new Array();
MyClass.getInstanceBySomeRelevantParameter = function(param) {
for (var i = 0; i < MyClass.instances.length; i++)
if (condition(param))
return MyClass.instances[i];
}
...
success: function(event) {
MyClass.getInstanceBySomeRelevantParameter(event).someFunctionCall();
}
函数MyClass(){
MyClass.instances.push(这个);
}
MyClass.instances=新数组();
MyClass.GetInstanceBySomerElevationParameter=函数(参数){
对于(var i=0;i
您可以始终将方法绑定到此上,然后按如下方式使用它:
function MyClass() {
}
MyClass.prototype = {
firstFunction: function() {
var funct = someFunctionCall.bind(this);
$.ajax({
...
success: function() {
funct();
}
});
},
secondFunction: function() {
var funct = someOtherFunction.bind(this);
window.setTimeout(function() {
funct();
}, 1000);
}
};
对于属性,只需将它们分配给另一个变量。ES5添加了名为
bind
的标准方法,该方法允许您绑定函数的this
,以及前n个参数。在上面的示例中,您可以通过调用bind
来避免使用self
$.ajax({
...
success: function() {
this.someFunctionCall();
}.bind(this);
});
对于非ES5浏览器,您可以为其使用垫片,如以下所示:
作为辅助,我将避免在编码模式中使用
self
,因为self
被定义为一个全局变量,它等于window
,后者是全局范围。换句话说,如果您不小心忘记定义self
,您将以静默方式获取全局范围作为值,而不是异常。如果改用that
,您将得到一个异常(除非您上面的人定义了它)。我在JSFIDLE上胡闹了一下,得出了以下结论。它假定您使用的是顶级名称空间。这使得您只需要声明self一次(在底部)。我将该类包装在一个匿名函数中,这样self就不会有全局作用域。小提琴是:
我在js.YMMV中见过self、that和obj。我想我已经在Javascript中看到了十几次
self
,每一个都是这个
和那个
作为单词,基本上是对立的。但是我们希望他们指的是同一个对象。@Imp:这样想吧:“this”和“that”在英语中经常一起使用,而“this”指的是更接近的项;“那”指的是更遥远的一个。或者,“这个”是我的,而“那个”是别人的/不是我的。当您设置that=this
时,您准备将当前执行上下文的所有者对象传递给另一个执行上下文-this
指向另一个对象,因此that
引用的对象实际上是另一个更远程的项。我还看到了比that
更多的self
,我认为它更清晰,但更清晰的是更具描述性的东西,比如,在最初的示例中,var myClass=this
。在匿名函数中使用此
不会给您提供对MyClass
@HunterMcMillen的引用:在我所有的解决方案中,此
将是对MyClass
的引用。您介意向我解释一下它是如何工作的吗?我失踪了something@HunterMcMillen:ajax
通过设置上下文:
属性来设置回调的此
值。第二个使用函数.prototype.bind
将此
值永久绑定到函数,第三个使用$.proxy
,这有点像函数.prototype.bind的轻型版本。谢谢,这真的很有用;很抱歉怀疑:)我只想指出,您应该将原型的构造函数
属性设置为指向MyClass
,因为您将其设置为另一个对象。只需在代码中附加以下行:MyClass.prototype.constructor=MyClass代码>。这不会将self
设置为调用函数的元素。换句话说,方法中的self
将是App.MyClass.prototype
,而不是MyClass
实例。如果您定义的var=this方法中的code>,然后执行console.log(that==self)
在setTimeout
回调中,您将看到它返回false
.Hmm。很好,我没有主意了。这只是JavaScript的一个不幸方面。调用上下文不会隐式地传递给嵌套函数。所以你所能做的就是使用一种变通方法。