Показать сообщение отдельно
  #38 (permalink)  
Старый 23.09.2009, 11:53
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от B~Vladi
Мне они "не нравятся" из-за рассказов о проблемах с памятью... Вот я и пытаюсь разобраться...
В плане создания методов в конструкторе, думаю в этом нет большого смысла (если только не создаются какие-то индивидуальные методы для отдельных объектов по условию).

С другой стороны, возвращаясь к оптимизации с объединёнными объектами:

Сообщение от ECMA-262-3-RUS; 13.1.2
Если объекты O и P объединены, для них операторы сравнения == и === дают положительный результат.
Сообщение от ECMA-262-3-RUS; 13.2
На практике скорее всего окажется целесообразным объединять объекты типа Function только в тех случаях, когда реализация может доказать, что различия между их свойствами [[Scope]] не различимы, и в таких случаях можно повторно использовать один объект.
Т.е. говорится, что объекты b1 и b2 в примере ниже должны давать true на == и ===, т.к. их [[Scope]] идентичный (пример из стандарта):

function A() {
   function B(x) {return x* x;} 
   return B; 
}

var b1 = A(); 
var b2 = A(); 

// но все текущие реализации дают false
alert(b1 == b2); // false
alert(b1 === b2); // false


Но, там же, в стандарте написано:

Сообщение от ECMA-262-3-RUS; 13.2
реализация может, но не обязана, объединить b1 и b2. Более того, она может использовать для b1 и b2 один и тот же объект, поскольку нет возможности различить их свойства [[Scope]].
Означает ли это, что реализации не используют предложенную оптимизацию? Я не знаю, поскольку не анализировал исходники всех реализаций. Но, всё-таки, я думаю, что оптимизацию они делают, просто выдают false (почему-то. Почему? Не знаю. Чтобы знать точно, повторю, надо глубоко смотреть исходники или связаться с разработчиками и спросить).

С другой стороны:

function A(x) {
  this.test = function () {
    alert(x);
  };
}

var objects = [];
for (var k = 0; k < 3; k++) {
  objects.push(new A(k));
}


внутренняя функция "this.test", по определению, может быть и не объединена, т.к. каждый раз [[Scope]] будет разный, в виду того, что параметр "x" меняется. Т.е. структура [[Scope]] будет опять же идентична, но значения в [[Scope]] будут разные. Должны ли здесь функции быть объединены? По определению, нет. В реализациях - возможно (например, хранить [[Scope]]-ы функций отдельно, а сам объект функции, код её, будет один, но это только предположение).

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

В случае же, когда можно использовать один объект (как в примере с b1 и b2) - там новый объект создаваться не должен вообще.

Короче, говоря проще, создавать методы в конструкторе (и все схожие ситуации) - смысла большого нет, это повлечёт за собой расход памяти прямо пропорциональный количеству объектов.
__________________
Тонкости ECMAScript

Последний раз редактировалось Dmitry A. Soshnikov, 23.09.2009 в 12:12.
Ответить с цитированием