5

Ich habe einen Code, der einen Getter (aber keinen Setter, falls relevant) für einen Prototyp definiert. Der zurückgegebene Wert ist in 99,99% der Fälle korrekt; Das Ziel besteht jedoch darin, die Eigenschaft auf einen anderen Wert für ein bestimmtes Objekt auszuwerten.Wie "überschreiben" Sie eine definierte (Get-) Eigenschaft auf einem Prototyp?

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 

Wie kann die Eigenschaft für x, ein vorhandenes Objekt außer Kraft gesetzt werden, , so dass es belegbare ist (z. B. hat Verhalten Standardeigenschaft)?

Addendum: Während eine neue Eigenschaft (Wert oder Get/Set) auf x definiert werden kann, suche ich nach Stopp das Verhalten einer Eigenschaft im [Prototyp] und drehen Sie "bar" zurück in eine normale/Ad-hoc-Eigenschaft für die spezifische Instanz.

Antwort

5

Durch die Verwendung von Object.defineProperty auf 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>"); 
 
}

Ich suche, ob es einen Weg gibt, um das Verhalten einer Eigenschaft in der [Prototyp] und drehen „bar zu stoppen "zurück in eine normale/Ad-hoc-Eigenschaft.

Okay, das ist etwas anders, aber immer noch verwendet 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. Ich habe einige Änderungen an der Frage vorgenommen (hauptsächlich eine Klausel/Satz am Ende). Gibt es hauptsächlich eine Möglichkeit, die Eigenschaftsdefinition von einer bestimmten Instanz einfach zu "entfernen"? – user2864740

+0

@ user2864740: Nein, Sie müssen eine eigene Eigenschaft für die Instanz erstellen, die die Eigenschaft des Prototyps maskiert. du könntest es immer 'undefiniert' zurückgeben lassen, wenn du willst (und es nicht-aufzählbar machen), was ein bisschen so wäre, als wäre es nicht da: 'Object.defineProperty (x," bar ", {value: undefined}) ; ' –

+0

@ user2864740: Ich habe ein zweites Snippet hinzugefügt; Ich habe die Frage gegenüber dem obigen Kommentar gelesen, ich denke, sie sind etwas anders. HTH. –

Verwandte Themen