OO JavaScript-避免self=this

OO JavaScript-避免self=this,javascript,Javascript,当以面向对象的方式使用JavaScript时,有没有人知道如何避免声明var self=this?我经常看到它,我很好奇它是否只是你必须做的事情,或者是否真的有一种方法(也许是类库?)让你绕过它?我知道为什么有必要(这有功能范围)。但是你永远不知道外面会有什么聪明的方法 例如,我通常在JS中编写我的“类”: function MyClass() { } MyClass.prototype = { firstFunction: function() { var se

当以面向对象的方式使用JavaScript时,有没有人知道如何避免声明var self=this?我经常看到它,我很好奇它是否只是你必须做的事情,或者是否真的有一种方法(也许是类库?)让你绕过它?我知道为什么有必要(这有功能范围)。但是你永远不知道外面会有什么聪明的方法

例如,我通常在JS中编写我的“类”:

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,然后执行
console.log(that==self)
setTimeout
回调中,您将看到它返回
false
.Hmm。很好,我没有主意了。这只是JavaScript的一个不幸方面。调用上下文不会隐式地传递给嵌套函数。所以你所能做的就是使用一种变通方法。