Что делает оператор return внутри сеттера?
У меня есть следующий код:
var o = {};
o.a = 1;
var _value = 1;
Object.defineProperty(o,"a",{
set: function(value){
_value = value + 1;
console.log("log: ", value, _value);
return _value;
},
get: function(){
return _value;
}
});
В методе установки я увеличиваю значение _value
на единицу, прежде чем вернуть его. Поэтому, если я установлю oa = 5
, я ожидаю, что консоль напечатает 6
(хотя я понимаю, что возвращать значение из установщика обычно не имеет смысла). Однако, как показано в следующем фрагменте, консоль печатает 5
:
> o.a = 5;
log: 5 6 // from console.log;
5 // return; why does it == value and not value + 1?
> o.a;
6
> var i = o.a = 5;
> i;
5
> o.a;
6
Итак, мой вопрос, почему он возвращает 5
а не 6
?
Я надеюсь, что это не потому, что я сделал глупую ошибку в коде.
Ответы
Ответ 1
Давайте посмотрим на простое назначение:
Вывод Assignment Production: LeftHandSideExpression = AssignmentExpression оценивается следующим образом:
- Пусть lref является результатом оценки LeftHandSideExpression.
- Пусть rref является результатом вычисления AssignmentExpression.
- Пусть rval - GetValue (rref).
Таким образом, rval
присваивается значение, которое будет назначено левой стороне (oa
). В вашем случае 5
.
- Выбросьте исключение SyntaxError, если все условия истинны: [...]
- Вызовите PutValue (lref, rval).
Здесь значение присваивается левой стороне (PutValue(oa, 5)
). Как вы можете видеть, ничего не делается с тем, PutValue
возвращает PutValue
(он ничего не возвращает).
- Возвращает rval.
Он просто возвращает значение, которое было назначено, в вашем случае 5
.
Выражение присваивания всегда возвращает значение, которое было назначено.
Ответ 2
Вы ничего не можете вернуть из средства настройки свойств и просто получаете значение присваивания (это 5
потому что вы назначили 5
).
что делает возврат в сеттер?
Ничего. Лучше удалите этот оператор return
. В лучшем случае это игнорировалось.
Ответ 3
Значение выражения присваивания всегда равно присваиваемому значению:
var a;
console.log(a = 7); // logs 7
Это верно, независимо от того, является ли то, что вы назначаете, это переменная, свойство plain, setter, свойство только для чтения или что-то еще:
var a = {};
Object.defineProperty(a, "b", { value: 8, writable: false });
console.log(a.b = 9); // logs 9
console.log(a.b); // logs 8, because a.b is read-only
Как вы сказали сами, возвращаемое значение в сеттере бессмысленно, поэтому, когда вы использовали возвращаемое значение в своем сеттере, почему вы ожидали, что он действительно сделает что-нибудь особенное?
Ответ 4
Для меня, если я не делаю parseInt, он видит это как строку... Кроме того, вы не должны возвращать значение в setter. Этот код работает:
<html>
<head>
<script language="javascript" type="text/javascript">
var o = {};
o.a = 1;
var _value = 1;
Object.defineProperty(o,"a",{
set: function(value){
_value = parseInt(value) + 1;
console.log("log: ", value,_value);
},
get: function(){
return _value;
}
});
function setValueAndRefresh() {
before = o.a;
o.a = document.forms["myform"].input.value;
alert("before: " + before + "; after: " + o.a);
}
</script>
</head>
<body>
<form name="myform">
value: <input type="text" name="input" value="5" /> <input type="button" value="set" onclick="setValueAndRefresh()"/>
</form>
</body>
</html>