Цитата:
this.action1=function(){ /* код функции */; }, то оно будет создавать новую функцию при каждом вызове этого конструктора для построения объекта ? Если да, то тогда будет лучше для экономии памяти и времени делать в конструкторе так : function F (){ /* код функции */; }, this.action1=F ; ? |
kefi, нет. Всё-таки, слово "скрипт" получилось несколько путанным в этой формулировке (вот только недавно насчёт этого же вопрос был).
Перефразирую точнее: FD создается при входе в контекст исполнения, до построчного его выполнения. Если контекст один - глобальный, то тут можно сказать и "весь скрипт". Всего есть три контекста: глобальный, функция и eval (подробней - в ссылке ниже). Поэтому, при входе в функцию её Variable object (Объект переменных, пункт 10.1.3) наполняется снова. В случае же с Вашим конструктором, - да, функция будет создаваться каждый раз новая - для каждого порождаемого этим конструктором объекта. В первом случае, у Вас FE:
this.action1=function(){ /* код функции */; };
Такая функция, как было сказано, создаётся в рантайме и не воздействует на VO, однако, последующее присвоение её свойству this.action1 оставляет функцию в памяти (иначе FE можно выполнить только сразу при объявлении, т.к. в VO они не попадают и дальше вызвать их нельзя). Во втором случае, у Вас FD:
function F (){ /* код функции */; }
this.action1=F ;
И, хотя, эта функция будет создана при входе в контекст исполнения (до выполнения кода функции), всё равно, функция будет так же создана новая - для каждого объекта своя. Цитата:
function A(state) {
this.state = state; // у каждого объекта своё свойство
this.fn = function () {}; // тоже своё
function fn2() {}
this.fn2 = fn; // тоже своё
}
// а вот методы - описаны единожды,
// но так же доступны всем порождённым
// объектам - за счёт делегации к прототипу
A.prototype = {
constructor: A,
test: function () {
alert(this.a);
}
};
// можно и отдельно описывать методы в прототипе
A.prototype.test2 = function () {
alert(this.state + ' test2');
};
var a = new A(10);
var b = new A(20);
a.test(); // 10
b.test(); // 20
alert([
a.hasOwnProperty('state'), // true
b.hasOwnProperty('state'), // true
a.hasOwnProperty('fn'), // true
b.hasOwnProperty('fn'), // true
a.hasOwnProperty('fn2'), // true
b.hasOwnProperty('fn2'), // true
a.hasOwnProperty('test'), // false, нет родного свойства, возьмётся из прототипа
b.hasOwnProperty('test') // false, аналогично
]);
Ссылка: http://javascript.ru/ecma/part10#a-10. Особенно можно посмотреть пункт 10.1.3, именно там говорится, что (var'ы, FD, и формальные параметры) и когда (при входе в контекст исполнения) создаётся (попадает в Variable object функции). |
Цитата:
|
Цитата:
Но! Как же так получается для второго случая с FD, функция определяется единожды - еще до run-time, но опять каждый объект содержит отдельную копию тела функции ? Или все же не тела в обоих случаях, а ссылки на одно и тоже тело ? В чем причина? В ECMA упорно не могу догнать, что написано. PS Цитата:
|
Цитата:
|
Цитата:
function fn () {
var a = function _a() {};
function b() {}
}
Что произошло: 1. Входим в контекст исполения функции "fn": - Заполняется VO: VO['a'] - создалась переменная "а", значение undefined; VO['b'] - создалась FD "b"; 2. Выполняем код контекста функции "fn" (вот он, runtime контекста): - создалась FE "_a" - VO['a'] = FE "_a" Цитата:
name ---> блок кода Или:
function name() {
// блок кода
}
Далее, присваиваем _name ссылку (тип Reference) на тот же блок кода: var _name = name; name ---> блок кода <--- _name alert(name === _name); // true Старое имя связываем с новым блоком кода:
name = function () {
// новый блок кода
};
_name ---> блок кода
name ---> новый блок кода
alert(name === _name); // false
Восстанавливаем: name = _name; P.S.: а, отвлекался, долго писал, Zeroglif ответил уже. |
Цитата:
Что же получается, что если в теле функции опредлены внутренние функции, то при каждом вызове этой функции ( входе в ее контекст ) будут создаваться и компилироваться новые копии тел вложеных функций ? Но зачем их создавать заново, и компилировать заново, если и после первого одного входа в контекст внешней функции уже интерпретатору должно быть понятно, что текстуально все нутро этой функции определено и меняться более оно текстуально не будет ? Где же тогда рациональность спецификации ? |
Цитата:
С другой стороны стандарт предусматривает оптимизацию, разрешая 'joined objects', но я чего-то сейчас не вижу, чтобы этим кто-то пользовался. Внутренняя самодельная оптимизация наверняка существует, но нам это не важно, если это не противоречит установленной логике или не выпячивает разницу в скорости. |
2 Zeroglif > А ну так все же у вложенной функции для разных объектов разный 'scope chain' , но "при одном и том же 'body' " ?
Т.е. на каждом объекте замыкается только свой [[scope]], но текст тела для всех один общий ? |
Даже не знаю, как объяснять. Ну, вот вы видите внутри конструктора некую функцию:
this.x = function(){...}; Представьте, что вместо функции там объект: this.x = {}; Создавая "экземпляры", вы создаёте разные объекты 'this.x' иначе у каждого экземпляра был бы один и тот же. Та же самая история с функциями, которые те же объекты, только сложнее. У них разница усиливается необходимостью удерживать scope chain, которая (цепь) теоретически всегда разная, т.к. создаётся в момент вызова и "привязывается" к создаваемой функции в момент создания. К тому же у каждой функции при создании есть пара - прототип будущих экземпляров, это тоже уникальная черта каждого потенциального конструктора. |
| Часовой пояс GMT +3, время: 03:35. |