:: Не фоксом единым
js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Решил почитать книжку "JavaScript для профессиональных веб-разработчиков", автор Николас Закас (Nicholas С. Zakas), издательство "Питер" 2015 год. Зачем читаю, отдельный разговор. Дошёл до места:




Исправлено 2 раз(а). Последнее : S-type, 27.12.16 17:45
Ratings: 0 negative/0 positive
js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Далее приводится поясняющий пример.




Исправлено 1 раз(а). Последнее : S-type, 27.12.16 18:08
Ratings: 0 negative/0 positive
js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Господа, Вы согласны с автором? Мне одному кажется, что тут что то не так?
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
Taran

Сообщений: 13624
Откуда: Красноярск
Дата регистрации: 16.01.2008
Local loObj, loObj2
loObj = CreateObject('Empty')
setName(loObj)
MessageBox(loObj.Name) && Nikolas
loObj2 = CreateObject('Empty')
setName(@loObj2)
MessageBox(loObj2.Name) && Greg
Function setName(obj)
AddProperty(obj, 'name', 'Nikolas')
obj = CreateObject('empty')
AddProperty(obj, 'name', 'Greg')
EndFunc



Исправлено 1 раз(а). Последнее : Taran, 27.12.16 18:20
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Годный пример. В JS вариант setName(@loObj2) невозможен, о чём и пишется в книжке. Другое дело насколько часто подобный приём применяется в том же фоксе...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
В С и С++ передача параметра "по значению" - это когда в стек сохраняется само значение, а передача параметра "по ссылке" - это когда в стек сохраняется адрес объекта. Числа передаются "по значению", объекты и массивы - по ссылке. Так же, всегда можно узнать адрес, по которому хранится адрес объекта, и передать этот адрес (адрес адреса!) в функцию - в этом случае в функции для обращения к объекту придётся использовать звёздочку! Как сказал мой преподаватель Дроздов Ф.Н. - "эта звёздочка очень многим жизнь испортила". VFP штука гораздо более высокоуровневая, чем C/C++. На сколько понимаю, на VFP в случае setName(loObj) в функцию передаётся указатель на объект (указатель - это тот же адрес), в obj хранится указатель на объект. Когда внутри функции setName выполняется obj = CreateObject('empty'), в локальную переменную obj помещается указатель на другой объект. А в случае setName(@loObj2) в функцию передаётся адрес указателя на объект. Но, VFP штука высокоуровневая, и его разработчики прекрасно понимают, что адрес указателя на объект (адрес адреса) нужен именно для доступа к объекту (а не к адресу объекта). Потому, если в функцию передаётся "адрес адреса объекта", VFP понимает, что ему передали, и корректно обращается к объекту. По сути, пользователя избавляют от работы с адресами. Так вот. В случае setName(@loObj2) в obj содержится "адрес адреса объекта", и при выполнении obj = CreateObject('empty') адрес нового объекта сохраняется в "адрес объекта". При этом "адрес адреса объекта" не меняется! В своё время осознание этого факта мне немножко взорвало мозг.

Тут все согласны?



Исправлено 1 раз(а). Последнее : S-type, 28.12.16 09:31
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
of63

Сообщений: 25244
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Взорвало, согласны.
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Годный пример.

А такой пример?

Local loObj, loObj2
loObj = Createobject('Person')
setName(loObj)
Messagebox(loObj.cName) && Nikolas
loObj2 = Createobject('Person')
setName(@loObj2)
Messagebox(loObj2.cName) && Greg
Function setName(obj)
obj.cName='Nikolas'
obj = Createobject('Person')
obj.cName='Greg'
Endfunc
Define Class Person As Custom
cName=""
Enddefine

Igor Korolyov
В JS вариант setName(@loObj2) невозможен, о чём и пишется в книжке.
Разве? Передача объекта "по ссылке" это когда мы можем из функции менять объект, ссылка (указатель, адрес) на который передана. Т.е. объект находится "где то там", и есть другие указатели на объекты. Мы изменили объект, при этом все другие, у кого есть указатели на этот объект, увидят изменения в объекте. А изменение значения самого указателя на объект приводит не к изменению объекта, а к изменению указателя. Все остальные указатели на объект не меняются. Разве не так?



Исправлено 1 раз(а). Последнее : S-type, 28.12.16 10:14
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Описанный выше пример переписал на C#:

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var loObj = new Person();
setName(loObj);
Console.WriteLine(loObj.cName); // "Nikolas"
var loObj2 = new Person();
setName(ref loObj2);
Console.WriteLine(loObj2.cName); // "Greg"
}
static void setName(Person obj)
{
obj.cName = "Nikolas";
obj = new Person();
obj.cName = "Greg";
}
static void setName(ref Person obj)
{
obj.cName = "Nikolas";
obj = new Person();
obj.cName = "Greg";
}
}
class Person
{
public string cName = "";
}
}

Корректно перевёл? Сделать одну setName не получилось.



Исправлено 1 раз(а). Последнее : S-type, 28.12.16 16:12
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
На msdn.microsoft.com сказано:

Цитата:
Переменная ссылочного типа не содержит непосредственные данные; она содержит ссылку на эти данные. Если параметр ссылочного типа передается по значению, можно изменить данные, на которые указывает ссылка, например, значение члена класса. Однако нельзя изменить значение самой ссылки; то есть нельзя использовать одну ссылку для выделения памяти для нового класса и его создания вне заданного блока. Для этого передайте параметр с помощью ключевого слова ref или out.

Наверное, автор прав.
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
А такой пример?
По сути то же самое, но с явно описанным классом, не с Empty.
S-type
Передача объекта "по ссылке" это когда мы можем из функции менять объект, ссылка (указатель, адрес) на который передана.
Терминологическая проблема имеет место быть, да.
"Передача по ссылке" это всё-же не "передача ссылки". И если объекты (в C# только reference types! т.е. уже НЕ ВСЕ объекты) передаются в методы путём "передачи ссылки", то "передача ПО ссылке" это несколько другое - да, это по сути передача "адреса указателя", или, точнее "указателя на указатель".

S-type
Корректно перевёл? Сделать одну setName не получилось.
Это странно...
C# "строже" и требует писать ref И в декларации, И в точке вызова (при том сигнатура метода с параметром типа Type и с параметром типа ref Type совершенно чётко разделяется). Вот между ref Type и out Type разделения нету, и описать 2 метода где всё различие состоит только в том что в одном будет ref а в другом out - нельзя.
Т.е. вообще-то конкретно в этом примере сделать методы с ОДНИМ именем (определить такую перегрузку метода setName) вполне допустимо.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
S-type
Передача объекта "по ссылке" это когда мы можем из функции менять объект, ссылка (указатель, адрес) на который передана.
Терминологическая проблема имеет место быть, да.
"Передача по ссылке" это всё-же не "передача ссылки". И если объекты (в C# только reference types! т.е. уже НЕ ВСЕ объекты) передаются в методы путём "передачи ссылки", то "передача ПО ссылке" это несколько другое - да, это по сути передача "адреса указателя", или, точнее "указателя на указатель".
На самом деле, при передаче параметров в стек всегда что то сохраняется. Выходит, передать "по ссылке" нельзя - всё и всегда передаётся только "по значению", а передачи параметров "по ссылке" вообще не существует. Потому, вместо "ссылочные типы передаются по ссылке" будем говорить "для ссылочных типов 'по значению' передаётся значение ссылки"... Так?

Мне кажется, под терминами "передача по значению" и "передача по ссылке" надо понимать, "в стек засунута переменная" и "в стек засунут адрес переменной". Передача "по ссылке" переменной ссылочного типа - это уже третье, это передача адреса ссылки - по большому счёту это довольно лишнее, можно даже сказать "на фиг не нужное".

Igor Korolyov
S-type
Корректно перевёл? Сделать одну setName не получилось.
Это странно...
[...]
Т.е. вообще-то конкретно в этом примере сделать методы с ОДНИМ именем (определить такую перегрузку метода setName) вполне допустимо.
Даже если сделать методы с ОДИН именем (подкорректировал пример), сделать одну setName не получится - всё равно должно быть две функции setName.
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
Taran

Сообщений: 13624
Откуда: Красноярск
Дата регистрации: 16.01.2008
S-type
Даже если сделать методы с ОДИН именем (подкорректировал пример), сделать одну setName не получится - всё равно должно быть две функции setName.

И это же замечательно. Читабельность функций легче, головняков меньше. И помнить два названия функции не надо.
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
На самом деле, при передаче параметров в стек всегда что то сохраняется.
Не все системы пользуются стеком, и даже если пользуются, то не всегда параметры передаются через стек. Я бы не стал вообще заострять внимание на "внутренней реализации" вызова и передачи параметра. Важна семантика - передаём КОПИЮ значения/переменной, либо же передаём САМО это значение/переменную (так что вызываемый код может изменить её, не просто "использовать").
S-type
Выходит, передать "по ссылке" нельзя - всё и всегда передаётся только "по значению", а передачи параметров "по ссылке" вообще не существует. Потому, вместо "ссылочные типы передаются по ссылке" будем говорить "для ссылочных типов 'по значению' передаётся значение ссылки"... Так?
Опять ты уходишь в дебри реализации... Не важно это всё, передаются всегда какие-то байтики - либо в стеке (процессорном, или "среды исполнения"), либо в регистрах, либо в какой-то специальной области памяти... Но то как всё работает "внутри" должно волновать системных программистов - тех кто пишет компиляторы/интерпретаторы или "рантаймы" (среды исполнения байт-кода). Для прикладного разработчика вполне достаточно понимания вышеприведенного примера - в одном случае поменяли переменную, в другом - нет (но поменяли нечто С ПОМОШЬЮ данных хранящихся в этой переменной).
S-type
по большому счёту это довольно лишнее, можно даже сказать "на фиг не нужное"
"если звезды зажигают - значит - это кому-нибудь нужно?" (c)
Если метод должен создать новый объект для внешнего кода, то у него достаточно мало способов вернуть его наружу. Возвращаемое значение метода - но оно только одно (ну да, можно вернуть структуру/объект с полями/свойствами, в новых редакциях C# даже в автогенерируемый тип). Можно воспользоваться ref или out (по сути это разновидность ref не требующая наличия "начального значения" в передаваемой переменной). Так что вовсе это не "бесполезная фигня".
S-type
Даже если сделать методы с ОДИН именем (подкорректировал пример), сделать одну setName не получится - всё равно должно быть две функции setName.
Естественно, т.к. логика (код) должна быть разной у этих методов - и сигнатуры у них разные. Ну если вернуться к старому доброму Си, то int и int* это совершенно разные типы


------------------
WBR, Igor




Исправлено 1 раз(а). Последнее : Igor Korolyov, 28.12.16 18:54
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Важна семантика - передаём КОПИЮ значения/переменной, либо же передаём САМО это значение/переменную (так что вызываемый код может изменить её, не просто "использовать").

Для меня "значение" и "переменная" это разные вещи. Переменная - это место (физически - ячейка памяти), где хранится какое то конкретное значение.

"Передать копию значения [содержащегося в переменной]" - это то понятно. Это когда значение одной ячейки памяти записывают в другую ячейку памяти. "Передать копию переменной" - это то же самое, что "передать копию значения переменной". Тут всё понятно. Это - передача параметра "по значению"

А что, что такое "передать САМО значение" и "передать САМУ переменную"? У ячейки памяти нельзя изменить её адрес. Выходит, физически нельзя передать "саму переменную". Можно только передать адрес ячейки памяти (указатель на переменную). А потом с помощью косвенной адресации обратиться по указанному адресу. Это и есть передача параметра "по ссылке".
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Решил проверить - как же всё таки на С++ (именно со ссылкой, а не с указателем, как в С):

#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
string cName="null";
};
void setName(Person obj)
{
obj.cName= "Nikolas";
obj = Person();
obj.cName = "Greg";
}
void setName2(Person &obj)
{
obj.cName = "Nikolas";
obj = Person();
obj.cName = "Greg";
}
int main()
{
Person person = Person();
setName(person); // null !
cout << person.cName << endl;
setName2(person); // "Greg"
cout << person.cName;
return 0;
}

Теперь вот сижу, и думаю, почему после setName не вывелось "Nikolas"...
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Выходит, в первом случае person передан "по значению" - целиком запихнут в стек. Другого объяснения придумать не могу.
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Передача указателя в явном виде (и так же в явном виде его разыменовывание).

void setName3(Person *obj)
{
(*obj).cName = "Nikolas"; // obj -> cName = "Nikolas";
// obj = &Person(); // "Nikolas" // меняем сам указатель (со ссылкой так не получится - ссылку менять нельзя)
(*obj) = Person(); // "Greg"
(*obj).cName = "Greg"; // obj -> cName = "Greg";
}

Теперь, если вызвать setName3(&person); увидим "Greg".



Исправлено 1 раз(а). Последнее : S-type, 30.12.16 13:29
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
Рома

Сообщений: 1079
Дата регистрации: 06.06.2001
S-type
Выходит, в первом случае person передан "по значению" - целиком запихнут в стек. Другого объяснения придумать не могу.

С++ неявно объявил за тебя несколько членов (правило трех)

class Person
{
public:
//"Big three":
Person(const Person& other){ *this = other; }
Person& operator =(const Person& other) { cName = other.cName; return *this; }
~Person(){ cName.~string(); }
};

То есть в C++ передача по значению приводит к неявному вызову конструктора копии.

Person person = Person();
setName(Person(person)); //Copy here!
Ratings: 0 negative/0 positive
Re: js - по ссылке или по значениею
Рома

Сообщений: 1079
Дата регистрации: 06.06.2001
S-type
Передача указателя в явном виде (и так же в явном виде его разыменовывание).
void setName3(Person *obj)
{
(*obj).cName = "Nikolas"; // obj -> cName = "Nikolas";
// obj = &Person(); // "Nikolas" // меняем сам указатель (со ссылкой так не получится - ссылку менять нельзя)
(*obj) = Person(); // "Greg"
(*obj).cName = "Greg"; // obj -> cName = "Greg";
}

Теперь, если вызвать setName3(&person); увидим "Greg".

Ну так ссылка по сути и есть "безопасный указатель"
В том смысле, что setName3(nullptr) рухнет по access violation, а setName2(nullptr) не даст сделать компилятор
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 3 (Гостей: 3)

© 2000-2024 Fox Club 
Яндекс.Метрика