Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   хитросплетения Global,контекст,this,Reference (https://javascript.ru/forum/misc/3158-khitrospleteniya-global-kontekst-reference.html)

Gvozd 24.03.2009 17:21

Цитата:

Сообщение от kefi
Так а разве var Person=function ... не есть определение именованной , ей же присваивается имя ?!

нет.это анонимная функция.

kefi 24.03.2009 17:30

2 Gvozd >
Насчет анонимных функций как-то еще нужно проверить ...
И еще - ведь можно сделать var Person = function PPP ... // - результат не изменится !!
PS .
Что-то не получается меня со скобочками , опубликуйте пример, плз.

twolf 24.03.2009 17:32

читаем тут. http://javascript.ru/tutorial/basic/...aniie-funktsii

Gvozd,
в вашем примере сначала выводится person который определен с помощью function(виден везде), а var Person еще не определен.
После определения var Person заменяется соответствующая функция Person, и выводится новое значение

Gvozd 24.03.2009 17:38

function al(o){document.write(o,'<br>')} ;
al(Person) ;//здесь будет указана именованая функция.та, которая была объявлена последней
function Person() { al("zxc")   }   ;
al(Person) ;// та же ботва
var Person = function () {al("123")}; 
al(Person) ;//опаньки.появилась анонимная.ее и пишем
function Person() { al("qqq")   }   ;
al(Person) ; //та же ботва

al('-----------------') ;
	{
	//создали новый контекст исполнения
	al(Person_) ;//нету еще никакой функции
	function Person_() { al("zxc")   }   ;
	al(Person_) ;//каждая новая функция переопределяет старую
	var Person_ = function () {al("123")}; 
	al(Person_) ;//каждая новая функция переопределяет старую
	function Person_() { al("qqq")   }   ;
	al(Person_) ; //каждая новая функция переопределяет старую
	
	}

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

PS IMHO.

Gvozd 24.03.2009 17:39

Цитата:

Сообщение от twolf
в вашем примере сначала выводится person который определен с помощью function(виден везде), а var Person еще не определен.
После определения var Person заменяется соответствующая функция Person, и выводится новое значение

да. я так собственно уже и понял

kefi 24.03.2009 21:36

2 Gvozd > Дайте плз ссылку , в ECMA не нашел, не понял этой синтаксической структуры :
{
    //создали новый контекст исполнения
  // ....
}

Zeroglif 24.03.2009 21:47

http://javascript.ru/ecma/part10#a-10.1.3

Для объявленных функций:
Цитата:

Если в объекте переменных уже есть свойство с таким именем, заменить его значение и атрибуты.
Для переменных:
Цитата:

Если в объекте переменных уже существует свойство с именем объявленной переменной, значение свойства и его атрибуты не изменяются.
И не путайте "создание/конкретизацию переменных" при котором переменная наполняется свойством 'undefined' и обычное построчное наполнение переменной тем, что справа от знака 'равно'. Первое происходит на "нулевой" строке кода, второе - по ходу дела. В вышеприведённых примерах 'var Person' при конкретизации "слабее" 'function Person', переменная не создаётся, т.к. имя уже занято, слово 'var' мысленно можно зачеркнуть, оставив только присвоение "Person = ...". А уже присвоение выкидывает предыдущее значение, занятое функцией на нулевой строке.

Zeroglif 24.03.2009 21:48

Цитата:

Сообщение от kefi
Дайте плз ссылку , в ECMA не нашел

Это его раз(из)мышления, фигурные контекст не создают... ;)

Gvozd 24.03.2009 21:55

kefi,
блин даже не знаю.
термин взял из головы.
справки по тому что написал дать не могу, ибо теперь я не понимаю, почему оно так!)
походу такое поведение не подчиняется каким-либо стандартам
более того, поведение указанное мною в коментариях наблюдается только в мозилле. в остальных же все в порядке вещей, независимо от "контекста исполнения"
согласно стандартам должно быть так:
Цитата:

Сообщение от http://javascript.ru/tutorial/basic/functions
В отличие от ряда языков, блоки не задают отдельную область видимости. Без разницы - определена переменная внутри блока или вне его. Так что эти два фрагмента совершенно эквивалентны:

в опере и осле так и работает:
Код:

function Person() { al("qqq") }
function Person() { al("qqq") }
function () {al("123")}
function () {al("123")}
-----------------
function Person_() { al("qqq_") }
function Person_() { al("qqq_") }
function () {al("123_")}
function () {al("123_")}

в мозилле же такое:
Код:

function Person() { al("qqq"); }
function Person() { al("qqq"); }
function () { al("123"); }
function () { al("123"); }
-----------------
undefined
function Person_() { al("zxc"); }
function () { al("123"); }
function Person_() { al("qqq"); }

судя по всему в огнелисе в такой хитрой конструкции создается свой контекст, по правилам отличным от каких-либо стандартов.
протестируйте код ниже в огнелисе, и в другом браузере.
реально странные вещи творятся у огнелиса
function al(o){document.write(o,'<br>')} ;
al(Person) ;//здесь будет указана именованая функция.та, которая была объявлена последней
function Person() { al("zxc")   }   ;
al(Person) ;// та же ботва
var Person = function () {al("123")}; 
al(Person) ;//опаньки.появилась анонимная.ее и пишем
function Person() { al("qqq")   }   ;
al(Person) ; //та же ботва
al('-----------------') ;
    {
    //создали новый контекст исполнения
    al(Person_) ;//нету еще никакой функции
    function Person_() { al("zxc_")   }   ;
    al(Person_) ;//каждая новая функция переопределяет старую
    var Person_ = function () {al("123_")}; 
    al(Person_) ;//каждая новая функция переопределяет старую
    function Person_() { al("qqq_")   }   ;
    al(Person_) ; //каждая новая функция переопределяет старую
 
    }
al('-----------------') ;
(function(){
	
	
    //создали новый контекст исполнения
    al(Person__) ;//нету еще никакой функции
    function Person__() { al("zxc__")   }   ;
    al(Person__) ;//каждая новая функция переопределяет старую
    var Person__ = function () {al("123__")}; 
    al(Person__) ;//каждая новая функция переопределяет старую
    function Person__() { al("qqq__")   }   ;
    al(Person__) ; //каждая новая функция переопределяет старую
	
	})()
al('-----------------') ;
for(i=0;i<1;i++)
	{
    //создали новый контекст исполнения
    al(Person__1) ;//нету еще никакой функции
    function Person__1() { al("zxc__1")   }   ;
    al(Person__1) ;//каждая новая функция переопределяет старую
    var Person__1 = function () {al("123__1")}; 
    al(Person__1) ;//каждая новая функция переопределяет старую
    function Person__1() { al("qqq__1")   }   ;
    al(Person__1) ; //каждая новая функция переопределяет старую
	}

Dmitry A. Soshnikov 24.03.2009 22:03

Цитата:

Сообщение от Gvozd
нет.это анонимная функция.

Точнее, Function Expression (FE). FE может быть и именованной функцией:

var a = function a() {...};


Основных отличий FE от FD (Function Declaration) два:

1. FE создаётся в рантайме (тогда как FD создается до построчного выполнения скрипта);
2. FE не воздействует на Variable object (VO) функции/контекста.

Первый пункт, вроде, и так все знают (кто более-менее знаком с JS). Однако, во многих статьях он описан поверхностно, и в основном FE приравнивается лишь к анонимной функции (что и создаёт путаницу). В то время как, разновидностей FE гораздо больше.

(function a() {...}); // это тоже, например, FE
alert(a); // как видим, на VO это не повлияло, и такой переменной нет - ошибка.


Цитата:

Сообщение от Gvozd
//создали новый контекст исполнения al(Person_) ;//нету еще никакой функции

Туда же относится (к FE). В скобках может быть только FE (не важно, что лексически они записаны в виде FD), поэтому функции будут созданы в рантайме, а не до начала выполнения скрипта. Кстати, это правильное (согласно стандарту) поведение сейчас можно наблюдать только в Firefox (в остальных браузерах - там будут построены FD).

Новый контекст исполнения здесь не создаётся. Однако, в новых версиях, блок из фигурных скобок может создавать отдельный scope (если интересно, почитайте про let на MDC и т.д.).

upd:

Цитата:

Сообщение от Gvozd
судя по всему в огнелисе в такой хитрой конструкции создается свой контекст, по правилам отличным от каких-либо стандартов.

Повторю, как раз-таки, наоборот. В Firefox - правильное поведение, в остальных (пока) - неправильное.


Часовой пояс GMT +3, время: 08:58.