Javascript-форум (https://javascript.ru/forum/)
-   Оффтопик (https://javascript.ru/forum/offtopic/)
-   -   apply и call. В чём отличия? (https://javascript.ru/forum/offtopic/5156-apply-i-call-v-chjom-otlichiya.html)

Dmitry A. Soshnikov 21.09.2009 20:12

Цитата:

Сообщение от Riim
я имел в виду аккуратно удалять незначащие звенья в этой цепи

Да, по логике вещей такую оптимизацию можно сделать (и скорей всего, движки делают что-то подобное, но в любом случае, чтобы знать точно - надо проанализировать все исходники движков). На уровне же специфиации - все функции, всегда, без исключения, запоминают Scope свойством [[Scope]].

Цитата:

Сообщение от Riim
можно не запоминать AO(контекста "B") и из "C" сразу в "A" ссылаться.

Тут есть важный нюанс - на момент активации "B", функция "А" уже может не существовать. А функция "С" создаётся функцией "B". Соответственно, чтобы получить доступ к объекту активации контекста функции "А", "С" должна обратиться к Scope контекста "B" и запомнить этот Scope, как C.[[Scope]].

JSprog 21.09.2009 20:32

Цитата:

Сообщение от B~Vladi
А и ещё один вопрос - чтобы не плодить тем... Не могу найти описание хитрой конструкции:

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

ГГ
А кстате prototype и [[prototype]] вначале указывают на одно и тоже?
А то в функции extend prototype==new Object() а [[prototype]]==Function.prototype
Так в начале

B~Vladi 22.09.2009 10:38

Цитата:

Сообщение от Dmitry A. Soshnikov
чтобы знать точно - надо проанализировать все исходники движков

Может прозвучит глупо, но их как-то можно достать?! Хотя с другой стороны для каждого браузера это личное достижение:)

И ещё небольшая просьба - не могли бы вы привести пример неправильного использования памяти на примере замыканий?! Т.е. интересует не только утечка, но и просто нерациональное расходование... Если такое, конечно, возможно в данном контексте...

Dmitry A. Soshnikov 22.09.2009 12:14

Цитата:

Сообщение от B~Vladi
но их как-то можно достать?!

http://en.wikipedia.org/wiki/JavaScript_engine

Там же есть ссылки на скачивание open-source движков. Некоторые, например, SpiderMonkey, можно посмотреть online.

Цитата:

Сообщение от B~Vladi
пример неправильного использования памяти на примере замыканий?! Т.е. интересует не только утечка, но и просто нерациональное расходование

Ну, про утечки в IE с циклическими ссылками вам и так известно. Насчёт расходования памяти, надо почитать про объединённые объекты, т.к. они могут вносить оптимизацию: 13.1 и 13.2.

Если [[Scope]] функций не различим, можно повторно использовать один и тот же объект.

B~Vladi 22.09.2009 17:34

Цитата:

Сообщение от Dmitry A. Soshnikov
Ну, про утечки в IE с циклическими ссылками вам и так известно.

Да, я стараюсь обходится без этого.
Цитата:

Сообщение от Dmitry A. Soshnikov
надо почитать про объединённые объекты

Спс, почитаем:)

x-yuri 23.09.2009 00:43

Цитата:

Сообщение от B~Vladi
Читал стандарт языка, но ответа не нашел... Заметил, только что в call можно передавать много аргументов...

call удобно использовать в начале цепочки вызовов, а apply - при дальнейшей передаче параметров
var o = {...};
function a() {
    ...
    b.apply( o, arguments );
}
function b() { ... }
a.call( o, 1, 2, 3 );


Цитата:

Сообщение от B~Vladi
Вот пытаюсь писать "грамотные" скрипты... Не нравятся замыкания... Вот разбираюсь...

Цитата:

Сообщение от B~Vladi
Как мне создать ф-цию, передать ей аргументы и оградить от внешнего [[scope]]?

ты стремишься не использовать замыкания? Вроде уже нечего особо бояться, утечек быть не должно, судя по http://javascript.ru/tutorial/events...ha-iyunya-2007 . Могут быть разве что псевдоутечки

B~Vladi 23.09.2009 11:18

Цитата:

Сообщение от x-yuri
ты стремишься не использовать замыкания?

Не совсем... Мне они "не нравятся" из-за рассказов о проблемах с памятью... Вот я и пытаюсь разобраться... А на самом деле очень удобно:)
Способ известен, будем применять:)

Dmitry A. Soshnikov 23.09.2009 11:53

Цитата:

Сообщение от 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) - там новый объект создаваться не должен вообще.

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

B~Vladi 23.09.2009 12:08

Цитата:

Сообщение от Dmitry A. Soshnikov
В плане создания методов в конструкторе, думаю в этом нет большого смысла

Да, я для этого использую prototype.
Цитата:

Сообщение от Dmitry A. Soshnikov
это повлечёт за собой расход памяти прямо пропорциональный количеству объектов

Пока я знаю только этот минус... И именно для такого случая (а такие возникают) я и хотел узнать способ создания анониймной функции в конструкторе, но с передачей (и сохранением) в неё значений нужных мне переменных.

Dmitry A. Soshnikov 23.09.2009 12:15

Цитата:

Сообщение от B~Vladi
И именно для такого случая (а такие возникают) я и хотел узнать способ создания анониймной функции в конструкторе, но с передачей (и сохранением) в неё значений нужных мне переменных

А в чём проблема? Переменные не "сохраняются" во вложенной функции? Не видны? Или что?


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