То, что вы хотите, не представляется возможным, потому что это в некотором роде противоречивой:
я хотел бы уменьшить syn("a").val
только syn("a")
так, что если я имею в виду syn("a")
без свойства или метода, он возвращает эквивалент syn("a").val
Предположим, что это было возможно, и значение, сохраненное для «а» 42, как в вашем примере, то оба из следующих выражений нужно будет возвращать 42:
syn("a")
syn("a").val
Но если первый возвращает 42, то второй не может работать: 42 не имеет свойства val
. Если второй работает, то первый обязательно вернет объект с свойством val
, который, очевидно, не является тем, что 42. Так что это противоречие.
По моему мнению, ближайший доступ к тому, что вы хотите, опирается на специальный метод valueOf
, который будет срабатывать при принуждении к числу (или булевому). Однако, чтобы это работало, вы должны предположить, что значения, которые вы храните, действительно являются числами.
Вот как это будет работать:
function Syn() { // constructor, so you can create more than 1 syn object
var container = {};
var f = function(variable){
return {
valueOf: function() { // special method
return container[variable];
},
val: container[variable],
assign: function(value){
container[variable] = value;
}
}
};
// Only include next line, if you REALLY need the returned
// object to be considered an instance of Syn:
Object.setPrototypeOf(f, Object.getPrototypeOf(this));
return f;
}
var syn = new Syn();
console.log(syn instanceof Syn); // true
syn("a").assign(42);
console.log(syn("a").val); // 42
console.log(+syn("a")); // 42, because `syn("a")` is coerced to number
NB: Я переименовал метод is
к assign
, как это кажется более значимым.
Аналогично valueOf
, вы можете рассчитывать на toString
, что делает подобную вещь, когда вы принуждать возвращаемое значение syn("a")
в строку:
function Syn() { // constructor, so you can create more than 1 syn object
var container = {};
var f = function(variable){
return {
toString: function() { // special method
return container[variable];
},
val: container[variable],
assign: function(value){
container[variable] = value;
}
}
};
// Only include next line, if you REALLY need the returned
// object to be considered an instance of Syn:
Object.setPrototypeOf(f, Object.getPrototypeOf(this));
return f;
}
var syn = new Syn();
console.log(syn instanceof Syn); // true
syn("a").assign("hello");
console.log(syn("a").val); // "hello"
console.log(''+syn("a")); // "hello", because `syn("a")` is coerced to string
Единственное, что странно, это ты доступ к контейнеру по индексу, когда контейнер является объектом. Для меня это не имеет смысла. Действительно ли это работает? – jdmdevdotnet
'is' звучит как тест равенства для меня, а не как сеттер. Я действительно предлагаю вам переименовать это. Кроме того, как бы вы хотели, чтобы это работало с новым синтаксисом getter? Если 'syn (" a ")' возвращает значение, оно также не может возвращать объект с помощью метода 'is' в одно и то же время. – Bergi
'container [variable]' если вы заметили скобки (обычно говоря, если это работает, то я не понимаю 100% того, как работают объекты в JS), это массив. Пример: 'container [1]' Вы обращаетесь к объекту в контейнере с индексом 1. Как вы обращаетесь к объектам, это будет больше похоже на это 'container.objectName'. Не помогает ваш вопрос вообще, только что я заметил. Выглядит странно, но если это сработает, я уверен, что есть веская причина. Просто любопытно посмотреть, что это такое. – jdmdevdotnet