apply и call. В чём отличия?
Читал стандарт языка, но ответа не нашел... Заметил, только что в call можно передавать много аргументов... Если есть ещё какие-нибудь отличия - напишите пжлст пример, где их можно посмотреть. Спс:)
|
А и ещё один вопрос - чтобы не плодить тем... Не могу найти описание хитрой конструкции:
var i=(function(){...})(); точно помню, что где-то было... Нужно именно описание, а не примеры... |
Цитата:
function sum(a,b) { this.c = a + b } var obj = {} sum.call(obj, 1,2) // или sum.apply(obj, [1,2]) alert(obj.c) // => 3 Цитата:
http://javascript.ru/forum/misc/4071...jj-vopros.html |
Цитата:
Цитата:
Цитата:
Цитата:
Но теперь я спокоен:) |
Получается, для того, чтобы выполнить JS-код не засрав при этом window можно использовать так:
(function(){...})() Будем иметь ввиду... Углубляться, думаю, не стоит - работает и хорошо:) |
Цитата:
если ты будешь внутри объявлять переменные или функции без var, то все равно засрешь |
Цитата:
У меня вот ещё какой вопрос: Например, есть такой код: function addClick(){ var i='New var'; ele.onclick=function(){ alert(i); } } Тут обычное замыкание и при каждом вызове addClick будет создаваться функция-обработчик. Так?! А что изменит такой код: function addClick(){ var i='New var'; ele.onclick=(function(){ return function(){alert(i)} })(); } Т.е. тут тоже замыкание, но я так понимаю, анонимная функция не будет клонировацо, т.к. отчищается после вызова... Мне самое главное понять, что остаёться в памяти... И ещё... В чём отличия записей: var f=function(){} и var f=(function(){}); Сори, если пишу глупости:) |
Цитата:
Цитата:
|
Аха, понятно...
Цитата:
Вот пытаюсь писать "грамотные" скрипты... Не нравятся замыкания... Вот разбираюсь... |
Ещё вопрос:
такой вариант оставит жить [[scope]] внешней функции: function(a,b){ var f=new Function(a,b,'return a+b'); } ?! Если да, то как этого избежать?! |
Получается, что нет:
alert( (function(a, b) { return new Function('return a + b;'); })(5, 6)() ); происходит ошибка, если бы функция создаваемая через "new Function" запоминала "a" и "b", то вывелось бы 11, как здесь: alert( (function(a, b) { return function() {return a + b}; })(5, 6)() ); |
Цитата:
В статье про замыкания есть такой код: function addEvents2(divs) { for(var i=0; i<divs.length; i++) { divs[i].innerHTML = i divs[i].onclick = function(x) { return function() { alert(x) } }(i) } } Т.е. как я понял,временная функция, после исполнения, возвращает уже функцию-обработчик, которая не использует внешних [[scope]] и, соответственно, нет никакого замыкания... Хоть бы это было так:) |
Цитата:
alert( (function() { return new Function('a','b','return a + b;'); })()(5, 6) ); |
Как же нет, "x" то он (обработчик) запомнил, кроме того внутри видны "i" и "divs".
|
ZoNT,
и что, где функция созданная через "new Function" запомнила что-то замыканием? |
Функция через new Function ничего не запоминает, так как формат её создания не подразумевает передачи в неё каких-либо ссылок...
|
Цитата:
:help: |
Цитата:
|
Цитата:
alert( (function(a, b) { return new Function('return ' + a + ' + ' + b + ';'); })(5, 6)() ); |
Это всё понятно... как передать внешнюю переменную в создаваемую ф-цию, не оставляя ссылки на scope?! Может можно как-то через prototype решить... Ну или в заранее созданную...
|
Цитата:
|
Цитата:
|
B~Vladi, можно через prototype, можно просто создавать нормальную структуру объектов, так что бы до всего нужного можно было добраться через window.
|
Ладно, не буду вас доставать:)
|
Цитата:
Цитата:
А в виду того, что любая функция хранит [[Scope]] (т.е. Scope chain порождающего контекста), все функции являются замыканиями. |
Цитата:
Есть код: function fnc1(){ var i; function fnc2(){ alert(i) } } А внешний [[scope]], который хранит функция fnc2 - это клон или ссылка на [[scope]] функции fnc1?! Т.е. меня интересует как при этом расходуется память... |
Цитата:
Цитата:
Т.е. f1.[[Scope]] === Scope глобальньного контекста === [Global] Scope (Scope chain) контекста функции f1 === Объект активации (AO) контекста функции f1 + f1.[[Scope]]: Scope(f1 Context) == AO(f1 context) + f1.[[Scope]] А f2.[[Scope]]: f2.[[Scope]] === Scope(f1 Context) === [AO(f1 context), Global] |
Dmitry A. Soshnikov, вот такой у меня вопрос: функция запомнила какие-то переменные, если внутри этой функции создать переменную, одноименную с той, что запомнена, то она как бы экранируется, теперь если экранируется все запомненное за счет имен аргументов, то хранится ли в памяти внешняя функция? Что-то у меня не получается создать пример подтверждающий или опровергающий это. Вот код для пояснения вопроса:
var p = (function() {// func1 var a = 5, b = 6; return function(a, b) {// смысла, хранить в памяти func1, вроде нет, все равно все экранировано, и убрать это экранирование вроде никак (delete применяется к свойствам объектов, но a и b непонятно чьи свойства) alert(a + b); }; })(); |
Цитата:
Т.е. одноимённые переменные (а также, декларации функций и формальные параметры) более глубокого контекста, разрешаются (определяются) раньше, чем переменные с тем же именем, но в контексте выше. Цепь областей видимости контекста (Scope chain) при нахождении в коде переменной, опрашивается интерпретатором от самого глубого звена цепи вверх до глобального объекта (и, в некоторых реализациях, прототипа глобального объекта). var a = 10; function A() { var a = 20; function B() { var a = 30; alert(a); // найдено сразу в AO(контекста B) } } Если бы переменная "а" была объявлена один раз (глобально), то при alert(a) из внутренней функции "B", она бы разрешалась по цепи (Scope chain контекста функции "B"): 1. AO(контекста "B") - (нет) -> 2. AO(контекста "А") - (нет) -> 3. VO(Global) === Global - (да) - 10 Цитата:
С другой стороны, одна вложенная функция может не иметь свободных переменных, а вложенная во вложенную может, поэтому, надо запоминать всегда, получается: function A() { var a = 10; function B() { // нужен ли этой функции Scope A? function C() { alert(a); // если B не запомнит Scope A, функция С не найдёт "а" } } } Но, повторю, по идее, может быть проведена оптимизация на уровне реализации. Поэтому, все функцию при создании запоминаю лексический контекст (т.е. Scope chain этого контекста), в котором они порождены, отсюда - все функции - замыкания. Функция может быть ни разу не запущена, но [[Scope]] уже в неё записался. Но, стандарт описывает предложение по оптимизации - объединённые объекты: function a() { function b(z) { return z * z; } return b; } var x = a(); var y = a(); Т.к. [[Scope]] функций x и y - не различим (и вообще, оба объекты - не различимы), реализация вправе использовать объединённые объекты в этом случае, или даже - использовать один объект. Поэтому, не всегда внутренняя функция будет создаваться каждый раз разная. |
Цитата:
function A() { var a = 10; function B() { // нужен ли этой функции Scope A? function C() { alert(a); // если B не запомнит Scope A, функция С не найдёт "а" } } } можно не запоминать AO(контекста "B") и из "C" сразу в "A" ссылаться. Правда я уже не уверен, что такая оптимизация пойдет на пользу, памяти конечно меньше надо будет, но при каждом создании функции столько дополнительной работы делать, с другой стороны там и так этой работы очень много делается. |
Цитата:
Цитата:
|
Цитата:
А кстате prototype и [[prototype]] вначале указывают на одно и тоже? А то в функции extend prototype==new Object() а [[prototype]]==Function.prototype Так в начале |
Цитата:
И ещё небольшая просьба - не могли бы вы привести пример неправильного использования памяти на примере замыканий?! Т.е. интересует не только утечка, но и просто нерациональное расходование... Если такое, конечно, возможно в данном контексте... |
Цитата:
Там же есть ссылки на скачивание open-source движков. Некоторые, например, SpiderMonkey, можно посмотреть online. Цитата:
Если [[Scope]] функций не различим, можно повторно использовать один и тот же объект. |
Цитата:
Цитата:
|
Цитата:
var o = {...}; function a() { ... b.apply( o, arguments ); } function b() { ... } a.call( o, 1, 2, 3 ); Цитата:
Цитата:
|
Цитата:
Способ известен, будем применять:) |
Цитата:
С другой стороны, возвращаясь к оптимизации с объединёнными объектами: Цитата:
Цитата:
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 Но, там же, в стандарте написано: Цитата:
С другой стороны: 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) - там новый объект создаваться не должен вообще. Короче, говоря проще, создавать методы в конструкторе (и все схожие ситуации) - смысла большого нет, это повлечёт за собой расход памяти прямо пропорциональный количеству объектов. |
Цитата:
Цитата:
|
Цитата:
|
Часовой пояс GMT +3, время: 16:40. |