5

У меня есть код, который определяет геттер (но нет сеттера, если таковой имеет значение) на прототипе. Возвращаемое значение верно в 99,99% случаев; однако цель состоит в том, чтобы установить свойство для оценки на другое значение для конкретного объекта.Как «переопределить» определенное свойство (get-) на прототипе?

foo = {} 
Object.defineProperty(foo, "bar", { 
    // only returns odd die sides 
    get: function() { return (Math.random() * 6) | 1; } 
}); 

x = Object.create(foo); 
x.bar  // => eg. 5 
x.bar = 4 // by fair dice roll 
x.bar  // nope => eg. 3 

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

Приложение: Если новое свойство (значение или get/set) может быть определено на x, я ищу, если есть способ: остановить поведение свойства в [прототипе] и включить «бар», обратно в обычное/ad-hoc свойство для конкретного экземпляра.

ответ

5

С помощью Object.defineProperty на x:

var foo = {} 
 
Object.defineProperty(foo, "bar", { 
 
    // only returns odd die sides 
 
    get: function() { return (Math.random() * 6) | 1; } 
 
}); 
 

 
var x = Object.create(foo); 
 
display(x.bar);  // E.g. 5 
 

 
(function() { 
 
    var bar; 
 
    var proto = Object.getPrototypeOf(x); // Or just use foo 
 

 
    Object.defineProperty(x, "bar", { 
 
    get: function() { return typeof bar !== "undefined" ? bar : proto.bar; }, 
 
    set: function(value) { bar = value; } 
 
    }); 
 
})(); 
 

 
display(x.bar); // Still odd 
 
x.bar = 4;  // By fair dice roll 
 
display(x.bar); // Shows 4 
 

 
function display(msg) { 
 
    document.body.insertAdjacentHTML("beforeend", "<p>" + msg + "</p>"); 
 
}

Я ищу, если есть способ, чтобы остановить поведение собственности в [прототип] и включите «бар «вернуться в обычное/ad-hoc свойство.

Хорошо, что это немного отличается, но все еще использует Object.defineProperty:

var foo = {} 
 
Object.defineProperty(foo, "bar", { 
 
    // only returns odd die sides 
 
    get: function() { return (Math.random() * 6) | 1; } 
 
}); 
 

 
var x = Object.create(foo); 
 
display(x.bar);  // E.g. 5 
 

 
Object.defineProperty(x, "bar", { 
 
    value: undefined, 
 
    writable: true, 
 
    enumerable: true // Or leave off if you want it non-enumerable 
 
}); 
 

 
display(x.bar); // undefined 
 
x.bar = 4;  // By fair dice roll 
 
display(x.bar); // Shows 4 
 

 
function display(msg) { 
 
    document.body.insertAdjacentHTML("beforeend", "<p>" + msg + "</p>"); 
 
}

+0

Clever. Я внесла некоторые изменения в вопрос (в основном предложение/предложение в конце). В основном, есть ли способ просто «удалить» определение свойства из определенного экземпляра? – user2864740

+0

@ user2864740: Нет, вам нужно создать собственное свойство в экземпляре, который маскирует свойство прототипа; вы можете заставить его всегда возвращать 'undefined', если хотите (и сделать его неперечислимым), что было бы немного похоже на то, что его не было:' Object.defineProperty (x, "bar", {value: undefined}) ; ' –

+0

@ user2864740: Я добавил второй фрагмент; прочитав вопрос против комментария выше, я думаю, что они немного разные. НТН. –