10

有谁知道在以 OO 方式使用 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);
    }

};
4

6 回答 6

6

在您的第一个功能中,您可以执行此操作...

$.ajax({
    context: this,
    success: function() {
        this.someFunctionCall();

    }
});

在第二个中,您可以这样做,但您需要.bind()在旧浏览器中填充...

window.setTimeout(function() {
    this.someOtherFunction();
}.bind(this), 1000);

使用 jQuery,您也可以这样做...

window.setTimeout($.proxy(function() {
    this.someOtherFunction();
}, this), 1000);
于 2012-07-25T01:40:51.583 回答
1

ES5 添加了调用的标准方法bind,允许您绑定this函数的前 n 个参数。self在上面的示例中,您可以通过调用来避免使用bind.

$.ajax({ 
    ... 
    success: function() { 
        this.someFunctionCall(); 
    }.bind(this); 
}); 

对于非 ES5 浏览器,您可以使用 shim,例如在此处找到的:https ://github.com/kriskowal/es5-shim

顺便说一句,我会避免self在您的编码模式中使用,因为self它被定义为一个全局变量,它等于window全局范围。换句话说,如果您不小心忘记定义self,您将默默地将全局范围作为值而不是异常。如果你that改用,你会得到一个异常(除非你上面的人定义了它)。

于 2012-07-25T02:03:52.110 回答
1

不,如果您想this在不同的上下文(例如回调)中引用,则需要这样做,否则它将被重新分配给另一个对象,例如window.

顺便说一句,self这是一个 python 约定——在 JavaScript 中人们通常使用该约定that = this。但这只是个人品味的问题。

于 2012-07-25T01:37:55.640 回答
0

我在 JSFiddle 上鬼混,并想出了以下内容。它确实假设您使用的是顶级名称空间。这使得你只需要声明一次 self (在底部)。我将类包装在一个匿名函数中,这样 self 就没有全局范围。小提琴是:http: //jsfiddle.net/bdicasa/yu4vs/

var App = {};
(function() {
    App.MyClass = function() { }

    App.MyClass.prototype = {

        firstFunction: function() {

            console.log('in first function');
            console.log(self === this); // true
        },

        secondFunction: function() {


            window.setTimeout(function() {
                self.firstFunction();
                console.log(self === this); // false
            }, 100);
        }

    };
    var self = App.MyClass.prototype;
})();

var myClass = new App.MyClass();
myClass.secondFunction();
于 2012-07-25T02:16:35.590 回答
0

一些 javascript 框架有自己的事件处理机制,允许您为处理函数设置上下文。这样self = this,您可以简单地指定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();
}
于 2012-07-25T01:43:26.283 回答
0

您可以始终将您的方法绑定到this然后按如下方式使用它:

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);
    }

};

对于属性,只需将它们分配给另一个变量。

于 2012-07-25T01:44:52.820 回答