Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 19.03.2009, 23:21
Аспирант
Отправить личное сообщение для no_alex Посмотреть профиль Найти все сообщения от no_alex
 
Регистрация: 20.08.2008
Сообщений: 56

Получить объект содержащий caller
Данная тема создана с целью разделить два вопроса смешанных в одной теме здесь:
Overloading в JavaScript

Вкратце повторю суть задачи.

Есть некий объект (A) у которого будут вызываться различные методы. И есть серия объектов (B1, B2, B3,...) которые будут обращаться к методам A.
У B1, B2, B3,... общий прототип (P). В прототипе P или в конструкторе, при создании объекта, я могу создать что-либо, что позволит потом получить ссылку на этот объект.

Теперь сама задача: когда B1, B2, B3,... обращается к методам A в этих методах я могу обратиться к "caller", но при этом я получаю ссылку на саму функцию прототипа P. А мне еще надо получить ссылку на объект у которого она была вызвана.

Пока объект B1 существует в единственном экземпляре проблем нет - я его цепляю к прототипу и потом легко получаю, но как только появляется B2, B3,... уже достучаться до текущего объекта не получается.


Объект A сейчас создается один раз и затраты на его создание сейчас большого значения не имеют. А вот объекты типа B будут создаваться регулярно и затраты на их создание мне надо максимально уменьшить. Т.е. минимализировать количество процедур в объекте B и аргументов передаваемых в объект A.

Т.е. надо усложнять объект A, для того чтобы максимально упростить вызов его методов из объектов B. Так-же не будет проблемой если мы усложним конструктор объекта B.


Теперь пример "не рабочего" кода, который я обещал привести:
var A = {
    t : function()
    {
        var this_func = arguments.callee; // Ссылка на текущую функцию
        var caller = this_func.caller; // Ссылка на вызывающую функцию (в данном случае я получаю ссылку на свойство из прототипа)
        var that = caller.ref // Попытка получить ссылку на объект из которого произошел вызов
        alert(that.x);
    }
}

var B = function(x)
{
	this.x = x; // Сохраняю свойство, для тестирования
	this.z.ref = this; // Пытаюсь сохранить ссылку на текущий объект, чтобы потом его получить. Но поскольку this.z фактически является свойством прототипа, это свойство потом презапишется
}
B.prototype = {
	x : "",
	z : function()
	{
		A.t();
	}
}


var B1 = new B("LALA1");
B1.z();
var B2 = new B("LALA2");
B2.z();


Ключевые моменты в коде я прокомментировал.

Если запустить код, том виде как я привел - вроде-бы все работает как надо. Мы получим, как и ожидаем два алерта: "LALA1" и "LALA2".

Но если изменить финальную часть этого кода, например так:
var B1 = new B("LALA1");
var B2 = new B("LALA2");
B1.z();
B2.z();

то все работает не правильно. Оба алерта будут "LALA2".

Хотелось бы получить что-либо подобное, но правильно работающее.
Ответить с цитированием
  #2 (permalink)  
Старый 19.03.2009, 23:44
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

хоть убейте до сих пор не пойму чем вам apply не подходит:
var A = {
    t : function()
    {
        alert(this.x);
    }
}
 
B = function(x)
{
    this.x = x; // Сохраняю свойство, для тестирования
}
B.prototype = {
    x : "",
    z : function()
    {
        A.t.apply(this);
    }
}
 
 
B1 = new B("LALA1");
B2 = new B("LALA2");
B1.z();
B2.z();
Ответить с цитированием
  #3 (permalink)  
Старый 20.03.2009, 00:00
Аспирант
Отправить личное сообщение для no_alex Посмотреть профиль Найти все сообщения от no_alex
 
Регистрация: 20.08.2008
Сообщений: 56

Цитата:
хоть убейте до сих пор не пойму чем вам apply не подходит
Потому что метод t() на самом деле очень сложный и мне надо в нем через this обращаться к другим свойствам объекта A.

Ну и вторая цель - вызовы из B1, мне надо сделать максимально простыми.
Сейчас я делаю примерно так:
var A = {
    t : function(that)
    {
        alert(that.x);
    }
}
 
B = function(x)
{
    this.x = x; // Сохраняю свойство, для тестирования
}
B.prototype = {
    x : "",
    z : function()
    {
        A.t(this);
    }
}
 
 
B1 = new B("LALA1");
B2 = new B("LALA2");
B1.z();
B2.z();

и потом получаю ссылку на текущий объект как аргумент метода t(). По сути, это даже проще, чем то что Вы предлагаете.

Но мне сейчас очень хочется отказаться от этого аргумента, если получится до него "достучаться" каким-либо другим способом.

Последний раз редактировалось no_alex, 20.03.2009 в 00:11.
Ответить с цитированием
  #4 (permalink)  
Старый 20.03.2009, 00:19
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

Сообщение от no_alex
Но мне сейчас очень хочется отказаться от этого аргумента, если получиться до него "достучаться" каким-либо другим способом.
почему?он вам сильно мозолит глаза?
или вы считаете что так будет медленнее?мне кажется навряд ли медленне, хотя не уверен
Ответить с цитированием
  #5 (permalink)  
Старый 20.03.2009, 00:30
Аспирант
Отправить личное сообщение для no_alex Посмотреть профиль Найти все сообщения от no_alex
 
Регистрация: 20.08.2008
Сообщений: 56

Gvozd,
Ну я же объяснил свои цели в начале:
Цитата:
Объект A сейчас создается один раз и затраты на его создание сейчас большого значения не имеют. А вот объекты типа B будут создаваться регулярно и затраты на их создание мне надо максимально уменьшить. Т.е. минимализировать количество процедур в объекте B и аргументов передаваемых в объект A.
Можно еще так сказать: Объект A сейчас создаю я. А вот объекты B1, B2, B3,... потом будут создавать другие люди. И у меня сейчас цель облегчить другим жизнь.
Но при этом сделать это так, чтобы это не вызвало путаницы.

Последний раз редактировалось no_alex, 20.03.2009 в 00:38.
Ответить с цитированием
  #6 (permalink)  
Старый 20.03.2009, 00:43
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

То есть усложнять конструктор B() и прототип создаваемых объектов нельзя?
ну, тогда не знаю как решить вашу задачу
Ответить с цитированием
  #7 (permalink)  
Старый 20.03.2009, 00:57
Аспирант
Отправить личное сообщение для no_alex Посмотреть профиль Найти все сообщения от no_alex
 
Регистрация: 20.08.2008
Сообщений: 56

Цитата:
То есть усложнять конструктор B() и прототип создаваемых объектов нельзя?
Конструктор усложнять можно. Там, на самом деле, конструктор будет только мой.
В прототипе так же можно создать какие-то вспомогательные методы, но только для того чтобы эти методы вызывались сами в какой-то момент. Чтобы тому кто будет писать B1, B2, B3,... не пришлось специально вызывать эти методы, иначе это будет сложнее чем передавать this через аргументы.
Ответить с цитированием
  #8 (permalink)  
Старый 20.03.2009, 01:09
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

я правильно понимаю:
var A = {
    t : function(that)
    {
        alert(that.x);
    }
}
 
B = function(x)
{
    this.x = x; // Сохраняю свойство, для тестирования
}
B.prototype = {
    x : "",
    z : function()
    {
        A.t(this);
    }
}
//выше находится ваш код.там творим, все что нам надо
//ниже код других людей.тут надо сделать чтобы все было максимально просто и прозрачно
 
B1 = new B("LALA1");
B2 = new B("LALA2");
B1.z();
B2.z();

если нет, то перенесите разделитель на подобающее место.
если же он там, то я не вижу усложнения рботы других людей
код ниже не менялся на протяжении всей темы
Ответить с цитированием
  #9 (permalink)  
Старый 20.03.2009, 01:34
Аспирант
Отправить личное сообщение для no_alex Посмотреть профиль Найти все сообщения от no_alex
 
Регистрация: 20.08.2008
Сообщений: 56

ok.
Вот так примерно работает тот скрипт, что у меня есть:
var A = {
    t : function(that)
    {
        alert(that.x);
    }
}
 
var B = function()
{
    this.tttt = 123; // Делаю что-то свое
    if(this.__constructor !== undefined && this.__constructor.constructor == Function) {
        this.__constructor.apply(this, arguments); // Вызываю "кастомерский" конструктор
    }
}
B.prototype = {
    some_special_method : function()
    {
    },
//выше находится наш код. Там творим, все что нам надо
//ниже код других людей. Тут надо сделать чтобы все было максимально просто и прозрачно
    x : "",
    __constructor : function(x) // Конструктор других людей
    {
        this.x = x; // Сохраняю свойство, для тестирования
    },
    z : function()
    {
        A.t(this);
    }
}
 
B1 = new B("LALA1");
B2 = new B("LALA2");
B1.z();
B2.z();


Теперь еще раз, с Вашего позволения, повторю задачу (для тех, кто возможно, не внимательно следил за нашим диалогом, но хочет сейчас к нему подключится).
Надо в этой строчке:
A.t(this);

избавится от this, но таким образом, чтобы в вызываемом методе получить ссылку на текущий объект.

Последний раз редактировалось no_alex, 20.03.2009 в 01:58.
Ответить с цитированием
  #10 (permalink)  
Старый 20.03.2009, 01:51
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

так подойдет?
var A = {
    t : function()
    {
        alert(this.x);
    }
}
 
B = function(qwe)
{
    this.x = qwe; // Делаю что-то свое
    if(this.__constructor !== undefined && this.__constructor == Function) {
        this.__constructor.apply(this, arguments);
    }
}

//конструкция, добавляющая A в верхнюю часть прототипирования
B_proto_constr=function(){}
B_proto_constr.prototype=A
B.prototype=new B_proto_constr()
//конструкция, добавляющая A в верхнюю часть прототипирования

    B.prototype.some_special_method = function()
    {
    };
//выше находится наш код. Там творим, все что нам надо
//ниже код других людей. Тут надо сделать чтобы все было максимально просто и прозрачно
    B.prototype.x = "",
    B.prototype.__constructor = function() // Конструктор других людей
    {
    };
    B.prototype.z = function()
    {
        this.t();//вынесли this из параметров.но приписали вначале))
    }
 
B1 = new B("LALA1");
B2 = new B("LALA2");
B1.z();
B2.z();

я решил добавить A в качестве прототипа прототипа объектов B
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Можно ли получить имя экземпляра объекта внутри самого объекта? Ichigeki Общие вопросы Javascript 9 14.11.2008 19:00
Получение ссылки на объект из метода Octane Общие вопросы Javascript 7 21.08.2008 15:09