Ссылаясь на переменную-член из собственной вызывающей вложенной функции - PullRequest
1 голос
/ 12 февраля 2012

У меня есть этот кусок кода

var f = function() {
    this.x = 100;
    (
        function() {
            x = 20;
        }
    )();
};

var a = new f;
console.log(a.x);

Мне интересно, почему новая переменная x создается в глобальной области видимости, а вывод 100, а не 20. Если я пишу вместо

var x = 100;

вложенная функция меняет то же значение x.Кажется, что создание x с помощью

this.x = 100

помещает x за пределы функции f.Если это так, где это определяется?И как к нему можно получить доступ?

РЕДАКТИРОВАТЬ: Исправлена ​​опечатка: console.log (ax) вместо console.log (x)

Ответы [ 5 ]

4 голосов
/ 12 февраля 2012

Инструкция:

this.x = 100;

Не создает переменную в текущей области, она устанавливает свойство x для любого объекта, на который ссылается this.В вашем случае this будет объектом, только что созданным с помощью new f, тем же объектом, который будет возвращен f и назначен на a.

Когда вы скажете:

x = 20;

JavaScript ищет x в текущей области и не находит его, поэтому он просматривает следующую область и т. Д. До тех пор, пока не достигнет глобальной области.Если он не находит x в какой-либо доступной области, он создает новую глобальную переменную, как вы видели.

Чтобы получить доступ к свойству x из вложенной функции, обычной практикой является сохранение ссылкина this в локальной переменной, а затем вложенная функция может ссылаться на эту переменную:

var f = function() {
    var self = this;       // keep a reference to this

    this.x = 100;
    (
        function() {
            self.x = 20;   // use the self reference from the containing scope
        }
    )();
};

var a = new f;
console.log(a.x);          // will now be 20

Другой способ сделать это - сослаться на this.x во внутренней функции, при условии, что вы вызываете внутреннюю функциюс помощью метода .call() , чтобы вы могли явно установить this таким же, как в (внешней) функции f:

var f = function() {
    this.x = 100;
    (
        function() {
            this.x = 20;
        }
    ).call(this);
};

var a = new f;
console.log(a.x);

Дальнейшее чтение:

1 голос
/ 12 февраля 2012

Если вы хотите изменить функцию-член во вложенной анонимной подфункции, вы можете создать указатель на 'this' в области видимости следующим образом:

var f = function() {
    this.x = 100; // set the member value
    var self = this; // pointer to the current object within this function scope
    (
        function(){
            self.x = 20; // 'self' is in scope
        }();
    )();
};

var a = new f;

console.log(a.x); // Output: 20
1 голос
/ 12 февраля 2012
var f = function() {

    this.x = 100;
    console.log(this);
    // f

    (function() {
      console.log(this);
      // DOMWindow. So x is a property of window because you're not declaring it with var
      x = 20;
    })();
};

если вы хотите назначить произведение анонимной функции на область действия f, будет работать следующее:

var f = function() {
    this.x = (function() {
      var x = 20; // Local scope
      return x;
    })();
};

console.log( (new f().x) );
1 голос
/ 12 февраля 2012

В javascript переменные имеют область действия на уровне функций. Также это:

this.x = 100;

отличается от:

x = 20;

потому что в более позднем случае x имеет глобальную (ранее вы не использовали var) область видимости, например, он становится частью объекта window.


Также, когда вы делаете:

var a = new f;
console.log(x);

Вы обращаетесь к глобальной переменной x, установленной через x = 20;, тогда как вы должны сделать:

var a = new f;
console.log(a.x);
0 голосов
/ 12 февраля 2012

Когда вы объявляете переменную без var, переменная находится в глобальной области видимости.

...