Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Ссылки/указатели в JS (https://javascript.ru/forum/misc/11148-ssylki-ukazateli-v-js.html)

Roman-NN 10.08.2010 10:05

Ссылки/указатели в JS
 
Есть ли в javascript возможность использовать ссылки/указатели (как & в php или в c++)?

Или может есть другое решение? В сущности, мне нужно создать многомерный массив с количеством уровней задаваемым в ходе выполнения программы. В ПХП реализовал бы с помощью указателей:
$p = $arr = array();
while ($condition) $p=&$p[0];

А как быть в йс?

Kolyaj 10.08.2010 10:15

В PHP не указатели, а ссылки.

Цитата:

Сообщение от Roman-NN
А как быть в йс?

var obj = {};  // В obj лежит ссылка на объект
var obj2 = obj;   // obj и obj2 ссылаются на один и тот же объект
obj.foo = 'bar';
alert(obj2.foo);

Roman-NN 10.08.2010 10:45

Большое спасибо, работает.

var p = a = {}; condition = 5;
while (condition--) p = p[0] = {}; // прячу значение поглубже
p[0] = 'Good morning';

p = a; condition = 6;
while (condition--) p = p[0]; // вывожу спрятанное значение
alert(p);


То есть, когда в операции присваивания справа стоит объект, то он всегда присваивается "по ссылке", т.е. новых объектов не создается?
А на переменную можно ссылаться только как на свойство объекта (как в строчке 3)? Специального оператора как в php нет?

Kolyaj 10.08.2010 10:58

Цитата:

Сообщение от Roman-NN
То есть, когда в операции присваивания справа стоит объект, то он всегда присваивается "по ссылке", т.е. новых объектов не создается?

Нет, справа стоит ссылка на объект, которая присваивается по значению. В JS невозможно в переменной хранить объект, только ссылку на него.

Цитата:

Сообщение от Roman-NN
А на переменную можно ссылаться только как на свойство объекта (как в строчке 3)? Специального оператора как в php нет?

Это не переменная, а примитивное значение. Передавать ссылку на него смысла нет, оно не мутабельное.

Т.е.
1. Нельзя хранить объекты, можно хранить ссылки на объекты.
2. Нельзя передавать по ссылке, но передаются ссылки на объекты.
3. Ссылок на примитивные значения нет, они смысла не имеют.

Вобщем, главное прочувтсвовать разницу: в PHP можно передавать по ссылке, в JS передаются ссылки.

А указатели это вообще другое.

Roman-NN 10.08.2010 11:07

Огромное спасибо! Все более и более проясняется, благодаря вам.
А что такое указателями я видимо основательно подзабыл, раз это другое. Надо будет почитать.
В общем, спасибо!

Roman-NN 12.08.2010 22:44

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

var a = Object ()
var b = Object ()
a.name = 'Alan'
b.name = 'Bob'

b = a // тут надо что-то похитрее

b.name = 'Bill'
alert(a.name+' а мне надо чтобы оставался Алан')


PS: Есть мысль сделать присвоение всех свойств в цикле, но тогда будет такая же проблема со свойствами, которые сами себе объекты. Можно конечно рекурсию сделать, но может в ЙС есть уже готовое решение?

PPS: Сразу в догонку, на всякий случай - мне нужно скопировать не простой объект, а [object CSSStyleDeclaration]. Но его же можно рассматривать как простой объект в данном случае?

Kolyaj 12.08.2010 22:55

Цитата:

Сообщение от Roman-NN
Есть мысль сделать присвоение всех свойств в цикле

Именно так.

Цитата:

Сообщение от Roman-NN
но может в ЙС есть уже готовое решение?

Нет.

Цитата:

Сообщение от Roman-NN
Но его же можно рассматривать как простой объект в данном случае?

Смотря какой у вас случай. Может поэтому и нет в JS функции для копирования объектов, случаи-то всегда разные.

Roman-NN 12.08.2010 23:04

Цитата:

Сообщение от Kolyaj (Сообщение 67227)
Смотря какой у вас случай. Может поэтому и нет в JS функции для копирования объектов, случаи-то всегда разные.

Грубо говоря, случай такой:
есть две ячейки таблицы с разными стилями. Через ЙС надо сделать стиль второй точь-в-точь как у первой (сохранив возможность менять стили по отдельности).

Честно говоря, я уже несколько отчаялся - иду в лобовое копирование нужных мне css-свойств

Kolyaj 12.08.2010 23:16

А страница-то не ваша чтоли? Такие проблемы решаются присвоением нужных CSS-классов.

Roman-NN 12.08.2010 23:22

страница моя, но стиль в ней очень динамично меняется с помощью ЙС

poorking 22.02.2011 20:12

Здравствуйте, чтобы не сорить новыми темами, решил написать тут, вопрос похожий

к примеру есть простенький конструктор
function constr(){
	var a = 0
	
	this.inca = function(){
		a++
	}
	
	this.geta = function(){
		return a
	}
}


создаем новый объект
var o = new construct()

и нужно получить копию этого объекта, а точнее ссылку на копию, а не на оригинал, чтобы применить один из методов в копии, изменяющих локальную переменную, есть ли такая возможность?
o.inca()

alert(o.geta())

var temp = o // так получим ссылку

temp.inca()

alert(o.geta()) //значение изменилось, но по задумке не надо бы ((


копирование всех свойств и методов в цикле не помогает, локальные переменные не копируются

B@rmaley.e><e 22.02.2011 21:02

Ну вызовите конструктор еще раз, в чем проблема?

Kolyaj 22.02.2011 21:13

Цитата:

Сообщение от poorking
есть ли такая возможность?

Нет.

А зачем?

poorking 22.02.2011 21:50

B@rmaley.e><e,
с новым вызовом конструктора не получится, потому как в конкретном случае конструктор генерирует некоторые локальные перемненные рандомно.
Kolyaj,
например:
function constr(){
	var r = Math.round(Math.random()*3)
	var a = 0;
	
	this.geta = function(){
		return a
	}
	
	this.calc = function(){
		switch(r){
			case 0:
				a = 0;
			case 1:
				a += 11
			break;
			case 2:
				a += 22
			break;
			case 3:
				a += 33
			break;
		}
	}
}

var o = new construct() //в экземпляре, на который получили ссылку есть локальная переменная, генерируемая рандомно (r)


нужно проверить, например, стоит ли выполнять calc().

если geta() возвращает после метода calc() больше, ну скажем 100, то не выполнять, иначе, выполнить

я хотел создать ссылку на копию объекта, выполнить calc(), проверить, и потом в зависимости от результата выполнять или не выполнять calc() по ссылке на оригинал

Kolyaj 22.02.2011 22:52

Такой конструктор вы сами написали? Отличный пример против приватизации переменных в JS.

poorking 22.02.2011 23:15

Ну приватизировать вроде получается, если я правильно понял
function constr(){
	var a = 0
	
	this.inca = function(){
		a++
	}
	
	this.geta = function(){
		return a
	}
}

var o1 = new constr()
	


var o2 = new constr()

o1.inca()
o1.inca()
o1.inca()


o2.inca()

alert(o1.geta()+"  "+o2.geta()) //у каждого своя приватная a

но вот значение в переменной хранить нельзя, придется тогда рандомную r, генерируемую в конструкторе, хранить как свойство и проверять
if(!(o.geta() + o.r>100)) 
   o.calc()

Kolyaj 22.02.2011 23:25

Цитата:

Сообщение от poorking
Ну приватизировать вроде получается, если я правильно понял

Конечно получается. Только это создаёт много не заметных с первого взгляда проблем. Ваша одна из таких.

poorking 23.02.2011 00:35

Понятно, тогда постараюсь избегать подобных ситуаций. Спасибо!


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