Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   ОПЕРАТОР ПРИСВАИВАНИЯ ПОЛУЧАЕТ ЗНАЧЕНИЕ ССЫЛКИ? (https://javascript.ru/forum/misc/23888-operator-prisvaivaniya-poluchaet-znachenie-ssylki.html)

Livanderiaamarum 10.12.2011 14:39

ОПЕРАТОР ПРИСВАИВАНИЯ ПОЛУЧАЕТ ЗНАЧЕНИЕ ССЫЛКИ?
 
var foo = {
  bar: function () {
    alert(this);
  }
};
 
foo.bar(); // Reference, OK => foo
(foo.bar)(); // Reference, OK => foo
 
(foo.bar = foo.bar)(); // global?


что происходит в последнем случае? Слева от скобок вызова находится не ССЫЛКА, а РЕАЛЬНОЕ ЗНАЧЕНИЕ ФУНКЦИИ. Но почему? Что поэтапно происходит? Как работает оператор присваивания? И что возвращают скобки " (foo.bar = foo.bar) " ? слева направа он работает или справа налево? Я думал что оператор смотрит что справа ссылка, достает ЗНАЧЕНИЕ обьекта из памяти по той ссылке. Генерирует новую ссылку относительно левого операнда, и кладет эту ссылку в левый операнд. И если все это дело взять в скобки, то скобки (которые не получают значение по ссылкам, а оставляют ссылки ссылками), то скобки должны вернуть левый операнд, а в нем лежит ссылка)), а у нас получается что возвращается не ссылка а РЕАЛЬНОЕ ЗНАЧЕНИЕ по ссылке. (в нашем случае это функция. (реальность значения, и то что оно не ссылка я определил по значению this, которое приняло значение глобального обьекта, а не базы ссылки, и такое происходит только если слева от скобок вызова реальное значение " VALUE() ", а не ссылка " REFERENCE() " ) )
а КАК НА САМОМ ДЕЛЕ работает оператор ровно что и как он достает и.т.п.)?
И почему в данном случае мы получаем реальное значение функции, а не ссылку на неё?

B@rmaley.e><e 10.12.2011 14:49

var foo = {
  bar: function () {
    alert(this);
  },
  toString: function () {
    return "Hello, I'm foo!"
  }
};

window.toString = function () {
  return "Hi, I'm a window"
};
 
foo.bar(); // Reference, OK => foo
(foo.bar)(); // Reference, OK => foo

*!*
 (foo.bar, foo.bar)()
*/!*
Проблема не в операторе присваивания, а в том, что в скобках стоит выражение, которые требует вычисления.
В первых двух случаях, как ни странно, выражения перед скобками вызова () нет.


Плохо написал. Напишу согласно стандарту:
1. Оператор группировки (те самые круглые скобки) не вызывает вычисление значения. Таким образом, ссылка, обрамлённая скобками, остаётся ссылкой.
2. Все остальные операторы вызывают вычисление значения. Таким образом, для ссылки вычисляется объект, на который она указывает. При том, для (obj.fnc, obj.fnc) результатом будет значение obj.fnc, то есть fnc без указания базы, т.е. fnc "открепится" от obj.
3. При вызове функции в качестве this будет использована та самая база, которую мы потеряли при вычислении значения.

Livanderiaamarum 10.12.2011 15:08

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 141746)
Проблема не в операторе присваивания, а в том, что в скобках стоит выражение, которые требует вычисления.
В первых двух случаях, как ни странно, выражения перед скобками вызова () нет.

1) какая еще проблема?) ни какой проблемы нет. есть вопрос как работает РОВНО. и я сделал пример.
2) и зачем вы заменили оператор присваивания запятой? О_О

B@rmaley.e><e 10.12.2011 15:13

Цитата:

Сообщение от Livanderiaamarum
и зачем вы заменили оператор присваивания запятой? О_О

Для демонстрации того, что это не специфичное поведение оператора присваивания, а общая черта почти всех операторов.

Livanderiaamarum 10.12.2011 15:17

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 141746)
Напишу согласно стандарту:
1. Оператор группировки (те самые круглые скобки) не вызывает вычисление значения. Таким образом, ссылка, обрамлённая скобками, остаётся ссылкой.
2. Все остальные операторы вызывают вычисление значения. Таким образом, для ссылки вычисляется объект, на который она указывает. При том, для (obj.fnc, obj.fnc) результатом будет значение obj.fnc, то есть fnc без указания базы, т.е. fnc "открепится" от obj.
3. При вызове функции в качестве this будет использована та самая база, которую мы потеряли при вычислении значения.

понятно) все кроме скобок является выражением и достает зачение сыслок. (это кстати я и так знал)
НО ЧТО ПРОИСХОДИТ ПОТОМ)? например в случае с РОВНО)?

var q = 20

(q = q) // что вернут скобки? значение или ссылку? Левого операнда ИЛИ правого?

можно расписать пошагово)? мыл оператор ровно смотрит что справа, потом достает, кладет и.т.п. Мне просто интересно ЧТО БУДЕТ ЯВЛЯТЬСЯ значением выражение в случае с ровно?

B@rmaley.e><e 10.12.2011 15:28

Оператор присваивания, как и запятая, вычисляет значение правого аргумента, которое и возвращает.

Возвращено будет значение правого операнда.

nerv_ 10.12.2011 15:44

Цитата:

Сообщение от Livanderiaamarum
НО ЧТО ПРОИСХОДИТ ПОТОМ)? например в случае с РОВНО

= <-- это не равно. Это оператор присваивания.
== <-- вот равно
=== <-- вот идентичность
==== <-- а вот....:D нет такого)

Livanderiaamarum 11.12.2011 00:20

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 141751)
Оператор, как и запятая, вычисляет значение правого аргумента, которое и возвращает.
.



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

Livanderiaamarum 11.12.2011 00:24

Цитата:

Сообщение от nerv_ (Сообщение 141753)
= <-- это не равно. Это оператор присваивания.
== <-- вот равно
=== <-- вот идентичность
==== <-- а вот....:D нет такого)

ты дурачек чтоле? в твоем случае ровно это "два ровно" а именно ==, а в моем случае это ровно то есть =. вобще что ли мозги отмороизл? не сочти за оскорбление, но ты совсем не воспринимаешь информацию.

Magneto 11.12.2011 00:45

В твоем случае и во всех случаях в JavaScript оператор "=" - oператор присваивания. Этот оператор присваивает значение правого операнда левому.

А равно это "==" - оператор сравнения на равенство. Этот оператор сравнивает два операнда и возвращает Булев результат.

И "===" - оператор тождества. Этот оператор сравнивает два операнда на равенство и возвращает Булев результат. И значения операндов, и их тип данных должны быть идентичны, чтобы оператор возвратил истину.

Так что тебе все верно сказали, и твои обзывания неуместны.

Livanderiaamarum 11.12.2011 00:57

12

Livanderiaamarum 11.12.2011 00:58

12





моё недоумение основано лишь на том что человек достаточно туп чтобы понять что я не написал РОВНО символом = а написал его словом РОВНО. из контекста это можно было понять, что впрочем все адекватные люди поняли это....

Livanderiaamarum 11.12.2011 00:59

12

Livanderiaamarum 11.12.2011 01:08

Цитата:

Сообщение от Magneto (Сообщение 141809)
В твоем случае и во всех случаях в JavaScript оператор "=" - oператор присваивания. Этот оператор присваивает значение правого операнда левому.

А равно это "==" - оператор сравнения на равенство. Этот оператор сравнивает два операнда и возвращает Булев результат.

И "===" - оператор тождества. Этот оператор сравнивает два операнда на равенство и возвращает Булев результат. И значения операндов, и их тип данных должны быть идентичны, чтобы оператор возвратил истину.

Так что тебе все верно сказали, и твои обзывания неуместны.

Дело в том что ровно это = а два ровно это ==, исходя из данного контекста моего повествования, если слушатель конечно не дурачек

B@rmaley.e><e 11.12.2011 01:54

Цитата:

Сообщение от Livanderiaamarum
В чем дело тогда, почему возвращается обьект?

Что? Возвращается ссылка на него.
var a = {};
(a = a).b = 5;
alert(a.b)

Livanderiaamarum 11.12.2011 08:40

var foo = {
  bar: function () {
    alert(this);
  }
};
 
foo.bar(); // Reference, OK => foo
(foo.bar)(); // Reference, OK => foo
 
(foo.bar = foo.bar)(); // Value => global?



в последней строчке скобки (foo.bar = foo.bar) возвращают Значение обьекта, а не ссылку на него. Почему?

nerv_ 11.12.2011 10:25

эт еще кто из нас дурачек :D Какие Reference? У вас идет проверка объекта вызова.
var foo = { bar: function() { alert("this === window: " + (this === window) + "\nthis === foo: " + (this === foo)); } };

foo.bar(); // foo
(foo.bar)(); // foo

(foo.bar = foo.bar)(); // window

B@rmaley.e><e 11.12.2011 11:15

Цитата:

Сообщение от Livanderiaamarum
Значение обьекта, а не ссылку на него. Почему?

Потому что они возвращают ссылку, а не значение объекта.
var foo = {
  bar: function () {
    alert(this);
  }
};

foo.bar.x = "Hello!";

(foo.bar = foo.bar).x = "lalala";

alert(foo.bar.x)

monolithed 11.12.2011 11:40

Livanderiaamarum,

var foo = function() {
     return this;
};

var bar = {
  baz: function () {
    return this;
  }
};

alert([
    foo(), //Window
    foo.prototype.constructor(), //Object 
    bar.baz(), //Object  
    (bar.baz)(), //Object 
    (bar.baz = bar.baz)(), //Window
    (bar.baz = bar.baz()), //Object
     bar.baz  //Object 
].join('\n'));


Рассмотрим подробнее, что происходит с:
(bar.baz = bar.baz)();

В этом случае, согласно спецификации вызывается метод GetValue().
Это значит, что тип Reference заменяется Function и вызов фунции происходит уже в Window, т.к. this будет null

var bar = {
  baz: function () {
    return this;
  }
};

var foo = bar.baz;
alert([
	foo(), //Window
	(some = bar.baz)(), //Window
	(1, bar.baz)() //Window
].join('\n'));

nerv_ 11.12.2011 13:16

Господа, добрый день :)

monolithed, разрешите задать два вопроса:
1.
Цитата:

Сообщение от monolithed
В этом случае, согласно спецификации

Можно ссылку?
2.
Цитата:

Сообщение от monolithed
т.к. this будет null

this будет window. Или я не прав?

Livanderiaamarum, практически цитата из книги:
Операции над элементарными типами производятся по значению, а над ссылочными типами – по ссылке.
Числа и логические величины – это элементарные типы; объекты - ссылочные. Массивы и функции – это специализированные типы объектов. Строки сравниваются по значению.

B@rmaley.e><e 11.12.2011 13:33

Цитата:

Сообщение от nerv_
this будет window. Или я не прав?

Нет. Стандарт гласит:
Цитата:

Значение this передаётся вызывающим. Если значение this, переданное вызывающим, не является объектом (заметим, что null - не объект), то значением this является глобальный объект.
Цитата:

Сообщение от nerv_
Строки сравниваются по значению.

Избыточное замечание. Строки — это тоже примитивы.
String.prototype.amIObject = "Nope";
var str = "string";
str.amIObject = "Yes!";
alert(str.amIObject)

nerv_ 11.12.2011 14:13

B@rmaley.e><e, спасибо, что тратите на меня время :) Перешел по ссылке "стандарт", прочитал. Хочу попросить Вас перейти по этой window, прочитать самое первое предложение, а после еще раз ответить на мой вопрос)

Цитата:

Сообщение от B@rmaley.e><e
Избыточное замечание. Строки — это тоже примитивы.

Java Script - Подробное руководство, 3.15.2. Копирование и передача строк, Флэнаган предполагает, что строки передаются по ссылке, но сравниваются по значению.
Ваш пример на данный момент понять не могу. Про prototype только читаю)))

p.s.: я не строю из себя умника. Просто хочу понять, как оно устроено :yes:

B@rmaley.e><e 11.12.2011 14:27

Цитата:

Сообщение от nerv_
прочитать самое первое предложение, а после еще раз ответить на мой вопрос

Так что Вам не нравится?
Цитата:

Сообщение от monolithed
вызов фунции происходит уже в Window, т.к. this будет null

При вызове функции в качестве this будет передан null. При вызове [[Call]] this будет определён согласно этому.

С тем, что window — глобальный объект и именно на него будет указывать this в этом случае, никто не спорит. Но вместе с тем, во внутренней механике стандарта используется именно null. window не берётся каким-либо магическим образом из окруженая. И, кстати, в strict mode ES5 this не становится глобальным объектом в случае
var a = function () {
  alert(this);
};

a();
a.call(null);
(a = a)();
"use strict";
var a = function () {
  alert(this);
};

a();
a.call(null);
(a = a)();
Цитата:

Сообщение от nerv_
Флэнаган предполагает, что строки передаются по ссылке, но сравниваются по значению.

Элементарные типы.
Фленеган же зачем-то погружается в особенности реализации, которые не зависят от стандарта и могут сильно варьироваться.
Строки наверняка реализованы с механизмом copy-on-write.

Livanderiaamarum 11.12.2011 17:38

Цитата:

Сообщение от monolithed (Сообщение 141912)
Livanderiaamarum,

var foo = function() {
     return this;
};

var bar = {
  baz: function () {
    return this;
  }
};

alert([
    foo(), //Window
    foo.prototype.constructor(), //Object 
    bar.baz(), //Object  
    (bar.baz)(), //Object 
    (bar.baz = bar.baz)(), //Window
    (bar.baz = bar.baz()), //Object
     bar.baz  //Object 
].join('\n'));

Рассмотрим подробнее, что происходит с:
(bar.baz = bar.baz)();
В этом случае, согласно спецификации вызывается метод GetValue().
Это значит, что тип Reference заменяется Function и вызов фунции происходит уже в Window, т.к. this будет null



Это я ЗНАЮ)! ну почему НИ КТО не читает внимательно текст топика)!!!!! Вот в чем вопрос, почему reference меняется на VALUE? От куда именно скобки берут ТО что возвращать мне?? Слева от ровно или справа? Слева от ровно по окончанию дествия лежит ссылка. справа тоже лежит ссылка. Значит скобки берут значение И НЕ СЛЕВА ОТ РОВНО и НЕ СПРАВА ОТ РОВНО, тогда откуда)?? или может происходит следущее??

(bar.baz = bar.baz)()


тут яваскрипт начинает вычислять то что в скобках.
и получает следущее

(bar.baz /*и тут ссылка*/ = bar.baz /*тут ссылка*/ )()



Простое присваивание ( = )
Значение нетерминала ВыражениеПрисваивания : ЛевостороннееВыражение = ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение ЛевостороннегоВыражения.
2. Вычислить значение ВыраженияПрисваивания.
3. Вызвать ПолучитьЗначение(Результа (2)).
4. Вызвать ЗаписатьЗначение(Результа (1), Результат(3)).
5. Вернуть Результат(3).


по скольку возвращается результат 3, то есть ЗНАЧЕНИЕ правого операнда ровно происходит следущее:

(baz /*тут ЗНАЧЕНИЕ*/)()



потом вступают в дело скобки группировки, и начинают смотреть ЧТО ВНУТРИ НИХ НИХ находится. смотрят - там значение, а не ссылка и возвращают значение. Дальше идут в ход скобки вызова и вызывают эту функцию делая её this равным global(null? но работает как global)

__________________________________________________

моя ошибка была в том что я думал что оператор ровно возвращает не ЗНАЧЕНИЕ правого выражения, а ссылку левого выражения)). и это я и пытался выяснить, и как оказалось тут очень мало людей понмиающих как работает javascript. но все ровно всем спасибо) пошел учить спецификацию.

monolithed 11.12.2011 17:49

Цитата:

Сообщение от Livanderiaamarum
Вот в чем вопрос, почему reference меняется на VALUE?

Важно запомнить, что this в контексте функции определяется caller'ом. И все, что определяется слева от () является типом Reference, в противном случае null, а т.к. нет практического смысла возвращать null подставляется Window.
Исходя из вышесказанного выражение типа:
(foo.bar = foo.bar)(); не определяются как Reference, именно по этому возращается Window (в basic mode).

Цитата:

Сообщение от nerv_
Можно ссылку?

11.1.6 Оператор группировки
11.2 Левосторонние выражения
11.13.1 Простое присваивание ( = )

Цитата:

Сообщение от nerv_
Флэнаган предполагает, что строки передаются по ссылке, но сравниваются по значению.

Можно предположить, что прототип функции примерно такой:
template <class T> T GetValue(const T &value);

В этом случае, формально значение передается по ссылке.

Livanderiaamarum 11.12.2011 18:29

можно ссылку?
-------------

держи
http://dmitrysoshnikov.com/ecmascrip...hapter-3-this/

nerv_ 11.12.2011 20:48

всем спасибо)
Цитата:

Сообщение от Livanderiaamarum
и как оказалось тут очень мало людей понмиающих как работает javascript

Не согласен. Вам (да и мне в том числе) уже по нескольку раз объяснили ув. B@rmaley.e><e и monolithed что да как.

B@rmaley.e><e 11.12.2011 22:54

Livanderiaamarum, читать спецификацию — хорошая идея. Возможно, тогда Вы поймёте, что ничто, кроме примитивов (элементарных типов в терминологии стандарта) по значению нигде в процессе выполнения программы появиться не может. Вы никогда не сможете получить объект по значению, только по ссылке.

Livanderiaamarum 11.12.2011 23:21

Цитата:

Сообщение от B@rmaley.e><e (Сообщение 142089)
Livanderiaamarum, читать спецификацию — хорошая идея. Возможно, тогда Вы поймёте, что ничто, кроме примитивов (элементарных типов в терминологии стандарта) по значению нигде в процессе выполнения программы появиться не может. Вы никогда не сможете получить объект по значению, только по ссылке.

вы говорите полный бред.

Простое присваивание ( = )
Значение нетерминала ВыражениеПрисваивания : ЛевостороннееВыражение = ВыражениеПрисваивания вычисляется по следующей схеме:
1. Вычислить значение ЛевостороннегоВыражения.
2. Вычислить значение ВыраженияПрисваивания.
3. Вызвать ПолучитьЗначение(Результа( 2)).
4. Вызвать ЗаписатьЗначение(Результа( 1), Результат(3)).
5. Вернуть Результат(3).


возвращается ИМЕННО VALUE правой стороны а не ссылка. если в правой стороне обьект то возвращается VALUE обеькта. Сколько можно уже это мусолить? вам же на примерах показали. Суть моего вопроса в том, ЧТО ИМЕННО возвращает ровно, как оно берет и что куда кладет. И как выяснилось возвращается не ссылка, а значение, которое посчиталось справа от знака ровно. Консоль показывала то же самое, но мне было интересно почему.


_______________________________________
п.с. получить обьект не по ссылке а по значению можно написав:
{a:20} //это обьект который не имеет ни какой ссылки, и я могу с ним работать в процессе выполнения кода
, что противоречит вашим словам, и именно по этому я и назвал их бредом. уж такое сморозить ЧИТАЯ спецификацию? стыдно должно быть вам.... вы наверное не даже не знаете про типы VALUE и REFERENCE ?

Livanderiaamarum 11.12.2011 23:30

пипец, зашел на этот сайт думая что тут профессионалы сидят.... обломался(((( тут оч мало народа который действительно шарит, в том числе и я((
что печально.

B@rmaley.e><e 11.12.2011 23:52

Цитата:

Сообщение от Livanderiaamarum
вы говорите полный бред.

А интерпретатор JS поддерживает меня в этом
var a = {b : 5};
(a = a).b = "String";

alert(a.b)

Livanderiaamarum 12.12.2011 13:59

Разобрался:

Значение this в контексте функции определяется вызывающей стороной (caller-ом) по форме вызова. Если слева от скобок вызова ( ), находится выражение типа Reference, то значением this будет являться базовый объект этого значения типа Reference. Во всех остальных случаях (т.е. при любом другом типе значения, отличном от типа Reference), значением this будет всегда являться null. Но, т.к. null особого смысла для значения this не несёт, автоматом подставляется глобальный объект.


в моем случае возвращается тип Function, в вашем возвращается Reference, которое скобки оставляют ссылкой. и да вы правы, типа данных обьект на этом уровне не может быть на прямую.

но вот вопрос. Как ОБЬЯСНИТЬ ЭТО?

({a:20}).b = 30


что это такое? что произойдет? какая ссылка есть на обьект? какая? какая база у ссылки? мы работаем с обьектом не имеющим ссылку??? О_О но это же невозможно..) и как тогда? как мы можем создавать свойство b ?? )))

я серьезно спрашиваю, я сам не догоняю))

мы создаем безымянный обьект в глобал области что ле ?

GuardCat 12.12.2011 14:14

Пардон за оффтоп: Livanderiaamarum, пожалуйста, умоляю, прекратите писать слово «равно» с буквой «о».

Livanderiaamarum 12.12.2011 14:30

Цитата:

Сообщение от GuardCat (Сообщение 142204)
Пардон за оффтоп: Livanderiaamarum, пожалуйста, умоляю, прекратите писать слово «равно» с буквой «о».

Такой уж у нас убогий нелогичный язык)) трудно в нем орентиорваться многие косяки приходится просто запоминать))

devote 13.12.2011 02:12

Цитата:

Сообщение от Livanderiaamarum
Такой уж у нас убогий нелогичный язык))

Дело далеко не в языке

trikadin 13.12.2011 07:36

Цитата:

Сообщение от Livanderiaamarum
Такой уж у нас убогий нелогичный язык))

Цитата:

Сообщение от devote
Дело далеко не в языке

:haha:

Хотя идиот, конечно. Ты ругаешься на всё, что не умеешь использовать?

monolithed 13.12.2011 08:31

Цитата:

Сообщение от Livanderiaamarum
Значение this в контексте функции определяется вызывающей стороной (caller-ом) по форме вызова. Если слева от скобок вызова ( ), находится выражение типа Reference, то значением this будет являться базовый объект этого значения типа Reference. Во всех остальных случаях (т.е. при любом другом типе значения, отличном от типа Reference), значением this будет всегда являться null. Но, т.к. null особого смысла для значения this не несёт, автоматом подставляется глобальный объект.

по-моему, я уже это упоминал?
Цитата:

Сообщение от monolithed
Важно запомнить, что this в контексте функции определяется caller'ом. И все, что определяется слева от () является типом Reference, в противном случае null, а т.к. нет практического смысла возвращать null подставляется Window.
Исходя из вышесказанного выражение типа:
(foo.bar = foo.bar)(); не определяются как Reference, именно по этому возращается Window (в basic mode).



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