Локальная переменная Javascript работает как переменная класса в окне - PullRequest
3 голосов
/ 05 августа 2010

Я нахожу такое поведение глобального окна объекта немного странным.

var x = 10;
function SomeClass(){
    var y = 15;
    console.log("Someclass:y - " + this.y); //prints undefined
}

console.log("window.x: " + window.x);   //prints 10

var obj = new SomeClass();
console.log("obj.y: " + obj.y); //prints - undefined

Обе переменные x и y являются локальными (для окна и SomeClass соответственно).Несмотря на вызов y из контекста объекта, он печатает только неопределенное - возможно потому, что именно так должны вести себя локальные переменные.Но window.x ведет себя иначе, печатая значение x.Я понимаю, что именно так вы создаете глобальные переменные, но является ли это специальное свойство window , которое заставляет локальные переменные вести себя как переменные объекта?

Ответы [ 4 ]

4 голосов
/ 05 августа 2010

В соответствии со спецификацией языка ECMAScript :

Если оператор переменной встречается внутри FunctionDeclaration, в этой функции переменные определяются с помощью локальной области действия функции,.].В противном случае они определяются с помощью глобальной области видимости (то есть они создаются как члены глобального объекта [...])

По сути это означает, что ключевое слово var имеет несколько другое значение внутри функциии в глобальной области видимости.

Я думаю, что один из способов взглянуть на это состоит в том, что создание переменной в глобальной области действия больше похоже на установку переменной экземпляра объекта после его создания, чем на установку локальной переменной.

Сравните установку локальной переменной в конструкторе:

function SomeClass(){ 
    var y = 15; 
} 

var obj = new SomeClass(); 
console.log("obj.y: " + obj.y); //prints - undefined 

и установку переменной экземпляра после создания объекта:

function SomeClass(){ 
} 

var obj = new SomeClass(); 
obj.y = 15;
console.log("obj.y: " + obj.y); //prints - 15
2 голосов
/ 05 августа 2010

Ключевым моментом, который нужно убрать, является то, что в вашем примере класса y является личным .

Как уже упоминалось другими, есть несколько способов сделать ее общедоступной переменной-членом, но я хотел бы упомянуть тот факт, что следующая структура:

function SomeClass(){
  var y = 15;
}

... может быть использована в ваших интересах, поскольку она является частной.

Обычно я использую несколько различных шаблонов для создания классов и объектов, но вы можете сделать одну полезную вещь - возвращать литерал объекта из вашей функции, в котором есть встроенные функции, которые могут ссылаться на y, но не подвергать y внешнему миру..

Вставьте этот пример на страницу, попробуйте его и увидите, что вы можете читать и писать в y, используя методы доступа:

<script type="text/javascript">
function SomeClass() {
  var y = 15;
  return {
    getY : function() { return y },
    setY : function(newY) { y = newY; }
  };
};

var obj = new SomeClass();

function showY() {
    alert("obj.getY: " + obj.getY()); // alerts current value of y.
}

function updateY() {    
    obj.setY(25);
    alert("updated.");
}

</script>
<input type="button" onclick="showY();return false;" value="showY"/>
<input type="button" onclick="updateY();return false" value="updateY"/>

Затем сначала нажмите «showY», затем«updateY», затем «showY» снова, чтобы увидеть поведение.

Это не единственный шаблон, который я лично использую, но javascript настолько гибок, что с ним можно сделать много забавных вещей.

Надеюсь, я вас не слишком обидели надеюсь, что это немного поможет с концепциями!

2 голосов
/ 05 августа 2010

вам нужно определить y как член SomeClass.В противном случае это просто локальная закрытая переменная в закрытии функции SomeClass, но не общедоступный член объекта SomeClass, поэтому:

function SomeClass(){
    this.y = 15;
    console.log("Someclass:y - " + this.y); //prints 15
}

Хороший вопрос, хотя переменная, назначенная глобальному пространству, также являетсяатрибут окна, не уверен насчет этого.Можно подумать, что вам понадобится

this.x="something"

, чтобы получить доступ к нему через window.x

2 голосов
/ 05 августа 2010

, чтобы достичь того, что вы пытаетесь с помощью переменной y, должно быть this.y = 15; Это позволит вам ссылаться на него через this.y, но также obj.y Причина, по которой он печатает undefined, заключается просто в том, что y неназначен членом SomeClass, как случайная переменная внутри него.

http://www.javascriptkit.com/javatutors/object.shtml

...