6

可能重复:
JS:var self = this?

在查看用 JavaScript 编写的任意代码时(例如在 GitHub 上),许多开发人员使用var self = this然后使用self而不是this来引用当前对象。

这种方法背后的基本原理是什么?

4

4 回答 4

9

The value of this is contextual. Writing var self = this is a way to save the value of this in one context so that it can be used in another.

Example:

function Test() {
    var self = this;
    console.log(this);
    setTimeout(function() {
        console.log(this);
        console.log(self);
    }, 1000);
}

Prints:

Test {}
Window 11918143#comment15869603_11918143
Test {}

Notice that the value of this has changed, but we can still refer to the original value using self.

This works because functions in JavaScript "close over" the variables in their lexical scope (which is just a more technical way of saying that the inner function can see variables declared in the outer function). This is why we write var self = this; the variable self is available to all inner functions, even if those functions don't execute until long after the outer function has returned.

于 2012-08-11T22:24:50.407 回答
5

例如,当您在 jQuery 中使用回调时,您可能希望引用父函数的this变量,一旦您在另一个函数中,该变量将采用不同的值:

$('#foo').click(function() {
  var self = this;

  $.get('foo.php', function(data) {
    // In here, self != this

    $(self).text(data);
  });
});

In this case, replacing $(self) with $(this) would not work. Basically, you're storing this in a variable for later use.

于 2012-08-11T22:23:35.770 回答
2

通常当您在某些代码中有嵌套函数声明但您想从“子”函数内部引用“父”函数时。

Ext.define('MyPanel', {
    extend: 'Ext.panel.Panel',

    title: 'My Panel',

    initComponent: function() {

        var self = this;

        Ext.applyIf(self, {
            items: [
                {
                xtype: 'button',
                text: 'MyButton',
                handler: function() {
                    console.log(this); //the button
                    console.log(self); //the panel
                }}
            ]
        });

        self.callParent(arguments);
    }
});

Ext.onReady(function() {

    var p = new MyPanel({
        renderTo: Ext.getBody()
    });


});​

例子:

http://jsfiddle.net/8F4UN/

于 2012-08-11T22:21:54.287 回答
2

Let me give a somewhat more technical explanation. When you access a variable in Javascript, the interpreter looks for the value of the variable in what's known as the scope stack. You can think of it as a stack of Objects. The interpreter will look first at the top of the stack. If the variable isn't defined in that scope object, it will look at the object beneath it. If it's not there, the interpreter looks another level down until it hits the bottom of the stack.

Initially, the only scope object in the stack is the global object. A variable is either there or not. When you call a function, the interpreter pushes a new object onto the scope stack--to be used for storing local variables. When you access var1, the interpreter will first look in the local scope object. If it's there, then it'll use the value stored there. If it's not, it moves on to the scope object further down the stack--which happens to be the global scope.

When you create a function within a function, something interesting happens. The interpreter will create what's known as an "activation object". It's basically a snapshot of the local scope object of the outer function. This activation object becomes associated with the inner function. When the inner function is called, the activation object is push onto the scope stack before the local scope (i.e. the local scope would still be at the top). Access of a variable in the inner function means the interpreter will first check the local scope object, then the activation object, then the global scope object.

By definition, the this variable always exists in the local scope of a function. It always refers to the implicit first argument. When you call a plain-o function, the compiler passes null as this. The variable exists, but points to null. A search for this would never look beyond the local scope object.

The purpose of the assignment to self is basically to fool the interpreter, so that it would look beyond the local scope of the inner function. When you access self in the inner function, the interpreter wouldn't find it in the local scope. So it checks the activation object. Provided that the self = this statement occurs before the creation of the inner function, self would exist in the activation scope object, pointing to the this object seen by the outer function.

于 2012-08-11T23:16:14.240 回答