Использование with
Кто нибудь может объяснить почему во всех браузерах кроме Firefox не работает вот такой код (вылетает ошибка в последней строке):
var obj = { test: function () {return 'done'} }; with (obj) { alert(typeof test); // 'function' var tryIt1 = function () { return test() + 1; } function tryIt2() { return test() + 2; } alert(tryIt1()); // 'done1' alert(tryIt2()); // ERROR: 'test' is undefined } P.S. Про опасности, связанные с использованием with я знаю. Хочется услышать теоретическое обоснование именно конкретного случая. |
функция tryIt2 создаётся до исполнения скрипта => ищет test внутри window
|
если не ошибаюсь, что определения функций с помощью
function tryIt2(){} являются глобальными, и сами функции создаются до выполнения самого скрипта(то есть вызвать ф-цию tryIt2() вы можете из любого места кода, даже ранее объявления самой ф-ции) таким образом ф-ция во время своего создания даже не подозревает, что она находится внутри with объявление же вида var tryIt1 = function () {} является локальным, и ф-ция создается во время выполнения кода. таким образов до этого места в коде она еще не существует. и когда создается, то она в курсе, что находится внутри with var obj = { test: function () {return 'done'} }; with (obj) { alert(typeof test); // 'function' alert((typeof tryIt1)+'|'+(typeof tryIt2)); // 'undefined|function' var tryIt1 = function () { return test() + 1; } function tryIt2() { return 2; //return test() + 1; } alert((typeof tryIt1)+'|'+(typeof tryIt2)); // 'function|function' } если я ошибаюсь, то поправьте меня.точно не могу вспомнить, что по этому поводу стандарт гласит в мозилле же ваш код работает, так как в ней все ф-ции создаются по ходу выполнения кода, а не заранее |
переменная test создаётся тоже до. а tryIt2 замкнута на переменную, а не на саму функцию => заполнить перемнную можно и после определения функии, но до её вызова.
|
Цитата:
|
Всё, кажется понял. Спасибо!
Поскольку конструкция function tryIt2() { ... } создает функцию непосредственно перед выполнением скрипта или обрамляющей функции, то в качестве области видимости она получает иерархию областей видимости текущего контекста исполнения (т.е. либо window либо эту обрамляющую функцию). А функция tryIt1 получает область видимости в момент создания уже с учетом with. Цитата:
|
Да. Вот так работает:
var obj = { test: function () {return 'done'} }; with (obj) { (function() { alert(typeof test); // 'function' alert((typeof tryIt1)+'|'+(typeof tryIt2)); // 'undefined|function' var tryIt1 = function () { return test() + 1; } function tryIt2() { return test() + 2; } alert(tryIt1()); // 'done1' alert(tryIt2()); // 'done2' })(); } :dance: |
Часовой пояс GMT +3, время: 04:04. |