2015-09-11 3 views
3

Я пытаюсь понять некоторые основные javascript.Как Javascript оценивает «это»?

У меня есть следующий фрагмент. У нас есть переменная name, которая в обоих случаях ссылается на метод getName.

Первые выходы предупреждения HocusPocus, а второй - GeorgeThomas. Но я не понимаю, как this относится к имени в этом случае

var name = 'Gerorge Thomas'; 
 
    var obj = { 
 
     name: 'Cinderella', 
 
     value: { 
 
      name: 'HocusPocus', 
 
      getName: function() { 
 
      return this.name; 
 
      } 
 
     } 
 
    }; 
 
    
 
    alert(obj.value.getName()); 
 
    var testing = obj.value.getName; 
 
    alert(testing());

ответ

4

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

Там есть список всех методов здесь: When you pass 'this' as an argument

Для вашего конкретного случая, когда вы делаете это:

var testing = obj.value.getName; 

Теперь у вас есть ссылка на функцию getName. У вас больше нет связи с obj.value. Итак, test() просто вызывает getName как обычную функцию. В Javascript, когда выполняется обычный вызов функции, значение this будет либо глобальным объектом (в браузере), либо в строгом режиме, оно будет неопределенным.

В вашем случае, this становится объектом window так this.name является window.name, который указывает на глобальную переменную name и, таким образом, вы получите результат "Gerorge Томаса.

Фактически, если вы запустите свой код в режиме strict, это вызовет ошибку, которая, по сути, является одним из преимуществ строгого режима, который указывает на случайные ошибки, подобные этому.


С другой стороны, если выполнить функцию с формой obj.method(), то this устанавливается равным obj. Итак, когда вы делаете:

obj.value.getName() 

, что эквивалентно:

var o = obj.value; 
o.getName() 

который является obj.method() форму вызова функции, которая будет задавать this указатель быть объектом, который в данном случае является obj.value.


Можно обойти эту проблему несколькими способами. Вот пример работы с ним, используя .bind().

var name = 'Gerorge Thomas'; 
 
var obj = { 
 
    name: 'Cinderella', 
 
    value: { 
 
    name: 'HocusPocus', 
 
    getName: function() { 
 
     return this.name; 
 
    } 
 
    } 
 
}; 
 

 
document.write(obj.value.getName() + "<br>"); 
 
var testing = obj.value.getName.bind(obj.value); 
 
document.write(testing());

1

Во-первых, вы вызываете метод из внутри obj объекта. Во второй раз вы делаете копию функции (не совсем, это просто ссылка) в глобальной области. Таким образом, вы также можете написать window.testing() для второго звонка. Я думаю, это ясно.

+0

да, это дает нам спасибо! – deroccha

+0

Отсутствует копия выполняемой функции - есть еще одна функция. Существует назначение ссылки на вторую переменную. Но это назначение не имеет ничего общего с проблемой OP. Проблема заключается в том, как вызывается функция. – jfriend00

+0

Небольшая техническая деталь, которая здесь не имеет значения, но я возьму ваше слово. – DanMan

2

Ну это нужно только некоторые размышления, давайте проанализируем его:

  • В первой тревоге мы называем getName() метод obj.value объекта, так он возвращает obj.value.name, который есть "HocusPocus".

alert(obj.value.getName()); мы называем this.name где это относится к obj.value так зовут HocusPocus

  • Но во втором начеку мы создаем новую функцию testing() с телом метода getName(), поэтому он будет прикреплен к глобальному объекту window, и если мы его назовем, мы получим глобальный name значение 'Gerorge Thomas'.

alert(testing()); мы имеем дело с this.nam е где this относится к глобальной области, так зовут 'Cinderella'.

Смежные вопросы