2013-03-06 4 views
1

В книге JavaScript Enlightenment (ссылка на предварительно опубликованную версию (стр. 85), но у меня есть опубликованная версия (глава 6.3), и она говорит то же самое), она говорит, что любая внутренняя функция будет обрабатывать this как глобальный объект (window) в ECMA-3, но будет установлен в ECMA-5.В JavaScript, будет ли какая-либо автономная внутренняя функция рассматривать это «как», в качестве объекта, на который был вызван исходный метод?

код ниже:

http://jsfiddle.net/javascriptenlightenment/9GJhu/

var myObject = { 
    func1: function() { 
     console.log(this); // logs myObject 
     var func2 = function() { 
      console.log(this) // logs window, and will do so from this point on 
      var func3 = function() { 
       console.log(this); // logs window, as it’s the head object 
      }(); 
     }(); 
    } 
} 

myObject.func1(); 

Но я думал, что в настоящее время Chrome, Firefox и node.js следует реализации ECMA-5 в значительной степени, поэтому я попытался выше код в них, и они все еще распечатывают глобальный объект внутри func2 и func3. Затем я добавил "use strict"; в func1 и на всякий случай, а также в func2 и func3. Код: http://jsfiddle.net/9GJhu/6/ Теперь в Chrome и node.js this будет распечатано как undefined, а не myObject. Так, согласно книге, this должен быть myObject в ECMA-5. Что не так в коде выше?

ответ

2

Возможно, я ошибаюсь, но я не видел нигде в спецификации, что подразумевает эта книга.
Согласно ECMAScript 5.1 specification 10.4.3 Ввод кода функции

  1. Если код функции строгий код, установите ThisBinding в thisArg.
  2. Иначе, если thisArg имеет значение null или undefined, установите значение ThisBinding для глобального объекта.
  3. Else, если Type (thisArg) не является объектом, установите значение ThisBinding для ToObject (thisArg).
  4. Else set ThisBinding to thisArg.
  5. Пусть localEnv является результатом вызова NewDeclarativeEnvironment, передающего значение внутреннего свойства F [F] в качестве аргумента.
  6. Установите LexicalEnvironment на localEnv.
  7. Задайте переменную окружения localEnv.
  8. Пусть код является значением внутреннего свойства F [[Code]].
  9. Выполнение обязательного связывания с использованием кодового кода функции и argumentsList, как описано в 10.5.

Согласно (1), так как ваш func2 и func3 не имеют никакого контекста, и вы указали strict mode ваш контекст будет установлен undefined. Без strict mode и в соответствии с (2.) this будет установлено значение window.

1

Когда вы используете директиву 'use strict', по умолчанию это ключевое слово 'undefined', в отличие от нестрогого режима, где ключевое слово this это ссылается на глобальный объект по умолчанию. Вам нужно явно указать контекст.

На боковой ноте вам нужно только объявить «использовать строгий» один раз.

0

Тот факт, что функции вложены, не означает ничего.Они продолжают работать так же, как и не вложен:

var myObject = { 
    func1: function() { 
     console.log(this); // logs myObject 
    } 
} 
myObject.func1(); 

var func2 = function() { 
    console.log(this) // logs window, and will do so from this point on 
}(); 

var func3 = function() { 
    console.log(this); // logs window, as it’s the head object 
}(); 

http://jsfiddle.net/NYr3y/2/

var myObject = { 
    func1: function() { 
     "use strict"; 

     console.log(this); // logs myObject 
    } 
} 

myObject.func1(); 


var func2 = function() { 
    "use strict"; 

    console.log(this) // logs window, and will do so from this point on 

}(); 

var func3 = function() { 
    "use strict"; 

    console.log(this); // logs window, as it’s the head object 
}(); 

http://jsfiddle.net/4B84u/2/

Первая функция называется с контекстом (как метод) и так, то «это» MyObject.

другие функции называются без контекста (как и func2()), и в этом случае ECMA-5 не позволяет явно не ссылаться на глобальный объект через это.

Большинство браузеров не применяют ECMA-5 по умолчанию, потому что не являются ретро-совместимыми, так как более ограничительные.