Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 06.01.2010, 18:56
Аватар для Pavel_Volodko
Интересующийся
Отправить личное сообщение для Pavel_Volodko Посмотреть профиль Найти все сообщения от Pavel_Volodko
 
Регистрация: 02.03.2009
Сообщений: 20

Использование 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 я знаю. Хочется услышать теоретическое обоснование именно конкретного случая.
Ответить с цитированием
  #2 (permalink)  
Старый 06.01.2010, 19:03
Профессор
Отправить личное сообщение для tenshi Посмотреть профиль Найти все сообщения от tenshi
 
Регистрация: 20.03.2008
Сообщений: 1,183

функция tryIt2 создаётся до исполнения скрипта => ищет test внутри window
__________________
.ня
Ответить с цитированием
  #3 (permalink)  
Старый 06.01.2010, 19:09
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

если не ошибаюсь, что определения функций с помощью
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'
}

если я ошибаюсь, то поправьте меня.точно не могу вспомнить, что по этому поводу стандарт гласит
в мозилле же ваш код работает, так как в ней все ф-ции создаются по ходу выполнения кода, а не заранее
Ответить с цитированием
  #4 (permalink)  
Старый 06.01.2010, 19:43
Профессор
Отправить личное сообщение для tenshi Посмотреть профиль Найти все сообщения от tenshi
 
Регистрация: 20.03.2008
Сообщений: 1,183

переменная test создаётся тоже до. а tryIt2 замкнута на переменную, а не на саму функцию => заполнить перемнную можно и после определения функии, но до её вызова.
__________________
.ня
Ответить с цитированием
  #5 (permalink)  
Старый 06.01.2010, 19:51
Профессор
Отправить личное сообщение для tenshi Посмотреть профиль Найти все сообщения от tenshi
 
Регистрация: 20.03.2008
Сообщений: 1,183

Цитата:
если не ошибаюсь, что определения функций с помощью
function tryIt2(){}
являются глобальным
нет, при создании контекста исполнения (вызове функции, запуске скрипта)
__________________
.ня
Ответить с цитированием
  #6 (permalink)  
Старый 06.01.2010, 19:59
Аватар для Pavel_Volodko
Интересующийся
Отправить личное сообщение для Pavel_Volodko Посмотреть профиль Найти все сообщения от Pavel_Volodko
 
Регистрация: 02.03.2009
Сообщений: 20

Всё, кажется понял. Спасибо!

Поскольку конструкция function tryIt2() { ... } создает функцию непосредственно перед выполнением скрипта или обрамляющей функции, то в качестве области видимости она получает иерархию областей видимости текущего контекста исполнения (т.е. либо window либо эту обрамляющую функцию). А функция tryIt1 получает область видимости в момент создания уже с учетом with.

Сообщение от Gvozd
в мозилле же ваш код работает, так как в ней все ф-ции создаются по ходу выполнения кода, а не заранее
Насчет Firefox-а - учтём-с.

Последний раз редактировалось Pavel_Volodko, 06.01.2010 в 20:23. Причина: Корректировка некоторых понятий
Ответить с цитированием
  #7 (permalink)  
Старый 06.01.2010, 20:05
Аватар для Pavel_Volodko
Интересующийся
Отправить личное сообщение для Pavel_Volodko Посмотреть профиль Найти все сообщения от Pavel_Volodko
 
Регистрация: 02.03.2009
Сообщений: 20

Да. Вот так работает:

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'
    })();
}


Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
jQuery Использование textIndent при анимации slim-v Opera, Safari и др. 26 19.12.2010 18:16
Использование load, динамически созданные объекты и добавление плагинов к ним. Alexander Majesty jQuery 2 11.12.2009 01:12
Использование web-optimizer progi2007 Серверные языки и технологии 2 17.08.2009 17:09
Использование jQuery.timers netlexx jQuery 7 23.12.2008 17:29
Использование метода setTimeout News Общие вопросы Javascript 3 18.09.2008 20:37