Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.126.11] |
|
Страницы: (11) « Первая ... 9 10 [11] все ( Перейти к последнему сообщению ) |
Сообщ.
#151
,
|
|
|
я не пропал, работаю
подойдем делу с другой стороны: function createPerson(name, age){ var person = {}; person.getName = function(){ return name; }; // замыкание name person.setName = function(value){ name = value; } // тоже person.getAge = function(){ return age; }; // замыкание age person.setAge = function(value){ age = value; } // тоже return person; } var gregory = createPerson('Gregory', 42), miller = createPerson('Miller', 30); gregory.getName(); // Gregory miller.getName(); // Miller gregory.getAge(); // 42 miller.getAge(); // 30 как думаешь (2K313), если бы функция имела одно определение для всех экземпляров объектов в данном случае, то как бы можно реализовать такое поведение? ну вот возмем к примеру функцию getName, как она возвращает разные значения имени? пробую сымитировать одно определение на все объекты, выношу определение функции и присваюваю ссылку на нее, в результате пустая строка: function getName(){ return name; }; function createPerson(name, age){ var person = {}; person.getName = getName; // ссылка на внешнюю функци person.setName = function(value){ name = value; } person.getAge = function(){ return age; }; // замыкание age person.setAge = function(value){ age = value; } return person; } var gregory = createPerson('Gregory', 42), miller = createPerson('Miller', 30); gregory.getName(); // '' miller.getName(); // '' gregory.getAge(); // 42 miller.getAge(); // 30 если не понятно, то объясню вызов getName во втором случае возвращает значение name глобального объекта, в случае броузера это window, т.е. window.name, а в первом случае getName и другие создают замыкания на локальные переменные, и каждый возвращаемый объект создает свою копию функции getName, которая замкнута на свою name, значение которого и возращает. жду комментарий можно с картинками пс. я работаю в бюро ритуальных услуг, делаю гробы, ну там саморезы завернуть или гвоздь забить спросите зачем там программирование? ну как же и там тоже нужен учет |
Сообщ.
#152
,
|
|
|
Цитата Cfon @ да думал я об этом уже тоже. не хочу опять на пол страницы тут расписывать, поэтому буду краток. ты же в С# шаришь...как думаешь (2K313), если бы функция Когда функция-конструктор вызывается, у неё составляется свой [[scope]] (так вроде называется) и там хранятся все текушие переменные (включая и переданные функции параметры и может ещё чего). Так вот, после того как функция своё отработала, все эти значения больше никому не нужны и занимаемая ими память освобождается. Когда же на какую-то из этих переменных (главное что она не глобальная, всмысле не window.aaa) есть замыкание (скажем внутри функции getName ), то текущий [[scope]] не уничтожается, а закидывается в <STRUCTUR type="function"> которая была только что создана (когда выполнялась строка getName = function( )... ) Возможно что в этом [[scope]] будет всё лишнее удалено и остануться только те переменные, на которые есть замыкание. Таким образом, когда позже вызывается getName( ), у неё есть все замкнутые переменные, значения которых были заданы ещё во время создания этой функции. Но это лишь мои предположения, так что если что не так - я не виноват. Получается что тело функции getName должно быть полюбому расспарсено сразу ещё при выполнении функции-конструктора, чтоб знать какие в ней переменные используются и на какие из них есть замыкание. Я вот только пока щас ещё не знаю, если внутри функции getName тоже делать присвоение функции (напр. getSupName = function ... и тоже с замыканием на какой нибудь переданный аргумент функции-конструктору (только не name, чтоб было видно что замыкание работает и через голову родителя), то будет ли эта переменная в ней видна??? Добавлено А код тела функции один на всех, который работает с текущей стуктурой <STRUCTUR type="function"> ссылку на которую, перед передачей управления исполняемому коду, закидывается скажем например в регистр eax и таким образом код работает с данными по этому адресу. но код один на всех! |
Сообщ.
#153
,
|
|
|
Цитата K313 @ Я вот только пока щас ещё не знаю, если внутри функции getName тоже делать присвоение функции (напр. getSupName = function ... и тоже с замыканием на какой нибудь переданный аргумент функции-конструктору (только не name, чтоб было видно что замыкание работает и через голову родителя), то будет ли эта переменная в ней видна??? да будет видна, например: function createPerson(name, age){ var person = {}; person.getName = function(){ return name; }; person.setName = function(value){ name = value; } person.getAge = function(){ return age; }; person.setAge = function(value){ age = value; } person.toString = (function(){ var s = name + ' is a '; return function(){ return s + age + ' years old.'; }; }()); return person; } var gregory = createPerson('Gregory', 42), miller = createPerson('Miller', 30); gregory.toString(); // Gregory is a 42 years old. miller.toString(); // Miller is a 30 years old. Добавлено Цитата K313 @ А код тела функции один на всех, который работает с текущей стуктурой <STRUCTUR type="function"> ссылку на которую, перед передачей управления исполняемому коду, закидывается скажем например в регистр eax и таким образом код работает с данными по этому адресу. но код один на всех! остается понять почему gregory.getName === miller.getName; // false известно, что функции в JS тоже являются объектами и выражение person.getName = function(){ return name; }; является присваиванием ссылки на объект-функцию, которая хранится как и все объекты в куче. заметь что в данном случае функция не имеет имени, т.е. является анонимной, следовательно у интерпретатора нет возможности заранее выделить ее в отдельное место в куче и потом присваивать ссылки на нее, он это делает непосредственно при вызове createPerson |
Сообщ.
#154
,
|
|
|
Цитата Cfon @ ну яне много другое вроде бы имел ввиду. потом напишу, ща влом...да будет видна, например: Цитата Cfon @ посмотри от сэда, сообщение #150остается понять почему Цитата K313 @ Тогда при встроенном методе, у каждого foo : <STRUCTUR> лежит ссылка на свой <STRUCTUR type="function">, то есть эта структура <STRUCTUR type="function"> у каждого объекта своя. |
Сообщ.
#155
,
|
|
|
Цитата K313 @ Цитата Cfon @ посмотри от сэда, сообщение #150остается понять почему Цитата K313 @ Тогда при встроенном методе, у каждого foo : <STRUCTUR> лежит ссылка на свой <STRUCTUR type="function">, то есть эта структура <STRUCTUR type="function"> у каждого объекта своя. нет я думаю ты ошибаешься под структурой что ты имеешь ввиду в JS носит название контекст выполнения функции, в котором сохраняются все локальные переменные функции. |
Сообщ.
#156
,
|
|
|
хотя возможно, что ты прав
вот что я увидел в Chrome Developer Tools на примере кода из поста №153 видно что методы каждого объекта имееют скрытое свойство [[FunctionLocation]], которое указывает на общее расположение кода. я так понял в книжках имелось ввиду, что сами методы (объекты-функции) у каждого объекта разные, которые имеют набор свойств, в том числе и указатель на сам код. также они имеют скрытое свойство [[Scopes]], где определены два объекта: Global и Closure. |
Сообщ.
#157
,
|
|
|
foo : <STRUCTUR> - это описатель самой foo, что это за зверь такой, переменная, объект, функция, undefined или число и так далее. И в этой структуре так же должен лежать адрес на память, где находится <STRUCTUR type="function">, которая уже является описателем самой функции, там уже побольше разных данных нужно держать...
Цитата Cfon @ я не понял, чего ты там хотел сделать...да будет видна, например: я же хотел попробовать наколоть функцию createPerson, чтоб она решила, что никаких замыканий на её текущий [[scope]] и он был бы уничтожен после завершения функции function createPerson(name, age){ var person = {}; person.getName = function(){ return 1; }; person.setName = function(value){ return 2; } person.getAge = function(){ return 3; }; person.setAge = function(value){ return 4; } person.toString = function(){ var s = {}; s.foo = function(){ var u = {}; u.foo = function(){ return name; } return u; }; return s; }; return person; } createPerson(name, age).toString().foo().foo(); |
Сообщ.
#158
,
|
|
|
Цитата K313 @ я не знаю какое у javascript при этом поведение должно быть, вернётся потом при вызове createPerson(name, age).toString().foo().foo(); вернется namе, потому что для замыкания не имеет значения глубина вложения функции,все к чему выше (по коду) идет обращение образует замыкание. Прикреплённый файлpic1.png (49,13 Кбайт, скачиваний: 311) Цитата K313 @ я же хотел попробовать наколоть функцию createPerson, чтоб она решила, что никаких замыканий на её текущий [[scope]] и он был бы уничтожен после завершения функции Скрытый текст function createPerson(name, age){ var person = {}; person.getName = function(){ return 1; }; person.setName = function(value){ return 2; } person.getAge = function(){ return 3; }; person.setAge = function(value){ return 4; } person.toString = function(){ var s = {}; s.foo = function(){ var u = {}; u.foo = function(){ return name; } return u; }; return s; }; return person; } наколоть не получится |
Сообщ.
#159
,
|
|
|
Цитата Cfon @ а если тело внучки в eval упаковать? наколоть не получится |
Сообщ.
#160
,
|
|
|
Цитата K313 @ Цитата Cfon @ а если тело внучки в eval упаковать? наколоть не получится хз предпочитаю не юзать ее вообще, также как new Function('код') имхо исполнять код переданный через строку это моветон, поэтому даже не буду предполагать что там дак Добавлено меня вот заинтересовало другое function foo() { return function(){ // some code }; } var bar1 = foo(); var bar2 = foo(); ... var barN = foo(); будет ли в этом случае ссылки на функции bar1...barN указывать на одно тело или таки каждая имеет свое тело? если сравнивать ссылки, то они указывают на разные функции, как и в случае с указателями на разные объекты bar1 === bar2; // false если в консоли Chrome напечатать bar1, то выводит просто определение функции function(){ // some code }; |
Сообщ.
#161
,
|
|
|
Цитата Cfon @ ты же знаешь моё мнение тело одно, структуры <STRUCTUR type="function"> разные.указывать на одно тело или таки каждая имеет свое тело Структура <STRUCTUR type="function"> для foo создаётся ещё во время парсинга, а для return function() каждый раз новая при каждом вызове foo( ); |
Сообщ.
#162
,
|
|
|
Цитата K313 @ Цитата Cfon @ ты же знаешь моё мнение тело одно, структуры <STRUCTUR type="function"> разные.указывать на одно тело или таки каждая имеет свое тело Структура <STRUCTUR type="function"> для foo создаётся ещё во время парсинга, а для return function() каждый раз новая при каждом вызове foo( ); да пожалуй что так Добавлено рассмотрим на примере function compare(a, b){ if (a < b){ return -1; } else if (a > b){ return 1; } else { return 0; } } когда определяется функция, интерпретатор парсит ее проверяет на синтаксис и если все в порядке создает объект в который заносит свойства { arguments: null caller: null length: 2 name: "compare" prototype: Object __proto__: function () [[FunctionLocation]]: VM227:1 [[Scopes]]: Scopes[1] -> 0: Global } тело, код или порядок выполнения инструкций, лежит по ссылке [[FunctionLocation]] VM227:1 это некий адрес в памяти когда происходит вызов var result = compare(10, 5); создается контекст выполнения, в котором формируется цепочка областей видимости [[Scores]] этой функции. далее в [[Scores]] запишется указатель на глобальную область видимость Global, тот что уже создан при определении функции, а также будет создан так называемый объект активизиции, в который будут хранится значения аргументов a=10, b=5, а также arguments. данный объект активизации (точнее его адрес) будет также добавлен в [[Scores]]. ну и собственно далее испольнение кода, результат которого будет записан в result. вроде все верно пс. позже обрисую происходящее в случае замыкания. |
Сообщ.
#163
,
|
|
|
рассмотрим замыкание на примере упрощенной версии функции createPerson:
var createPerson = function(name){ return { getName: function(){return name;}, setName: function(value){name = value;} }; }; var greg = createPerson('Greg', 42); интерпретатор создает определение функции createPerson, затем идет вызов createPerson('Greg', 42), создается контекст выполнения вида { getName: function () arguments: null caller: null length: 0 name: "getName" prototype: Object __proto__: function () [[FunctionLocation]]: VM241:3 [[Scopes]]: Scopes[2] 0: Closure (createPerson) name: "Greg" 1: Global setName: function () arguments: null caller: null length: 0 name: "setName" prototype: Object __proto__: function () [[FunctionLocation]]: VM241:4 [[Scopes]]: Scopes[2] 0: Closure (createPerson) name: "Greg" 1: Global __proto__: Object } видно, что отличие от примера без замыкания, в наличие дополнительного объекта Closure в котором хранится наше замыкание. ВСЕ РАЗОБРАЛСЯ! да понял я тело всегда одно, спасибо курящая обезьяна! |
Сообщ.
#164
,
|
|
|
Цитата Cfon @ это ведь не от нас с тобой зависит, а от того C#-шника, который этот очередной интерпретатор для javascript писал. Захочет он чтоб было много тел, так и будет их много. да понял я тело всегда одно Цитата Cfon @ да на здоровье, гробовщик, забивающий шурупы в крышку гроба спасибо курящая обезьяна! |
Сообщ.
#165
,
|
|
|
Цитата K313 @ это ведь не от нас с тобой зависит, а от того C#-шника, который этот очередной интерпретатор для javascript писал. Google Chrome V8 на С++ написан |