2010-09-30 19 views
8

Ich sehe Beiträge über ein 'neues' Object.create, das die Aufzählung konfigurierbar macht. Es beruht jedoch auf einer Object.defineProperty-Methode. Ich kann keine Cross-Browser-Implementierung für diese Methode finden.Object.defineEigenschaft in ES5?

Sind wir fest für das alte Object.create schreiben? Ich kann keine Dinge schreiben, die in IE6/7 nicht funktionieren.

+3

Es gibt immer Chrome-Frame! – kzh

Antwort

14

Es gibt mehrere Dinge, die man nicht aus der ECMAScript 5 Object.create Methode emulieren in einer ECMAScript 3-Umgebung.

Wie Sie gesehen haben, wird Ihnen das Argument Eigenschaften Probleme bereiten, da es in E3-basierten Implementierungen kein Weg gibt, um die Eigenschaftenattribute zu ändern.

Die Object.defineProperty Verfahren nach @Raynos erwähnt, arbeitet auf IE8, aber teilweise , kann es nur in DOM-Elemente verwendet werden.

Auch Accessoreigenschaften werden Sie Probleme geben, sie mit weitgehend unterstützt Nicht-Standard-Methoden nachgeahmt werden könnte wie __defineGetter__/__defineSetter__, aber wieder, Sie kann die Eigenschaft nicht Attribute ändern.

Ein weiteres Problem neben den Eigenschaftendeskriptoren ist, dass die Object.create-Methode null als Argument akzeptieren kann, um ein Objekt zu erstellen, das nichts erbt.

Dies kann nicht mit den Crockford's Object.create shim emuliert werden, denn wenn der new Operator mit einer Konstruktor-Funktion verwendet wird, die eine prototype Eigenschaft enthält null -oder andere nicht-Objekt wert- erben, das neu erstellte Objekt aus Object.prototype hat sowieso standardmäßig.

In einigen Implementierungen -V8, Spidermonkey, Rhino, etc ...- sie haben eine setteable __proto__ Eigenschaft, die verwendet werden könnten, ein null [[Prototyp]] auf, aber auch hier, das ist nicht-Standard, und sicher Es wird nie auf IE arbeiten.

Ich würde empfehlen, wenn Sie alte Browser verwenden möchten, um diese Funktionen nicht zu verwenden, da es keine Möglichkeit gibt, sie in diesen Umgebungen ordnungsgemäß zu funktionieren.

Wenn Sie noch Object.create verwenden, ohne die Eigenschaften Argument zu verwenden, Sie könnten, aber ich würde Ihnen empfehlen, die Dinge zu erkennen, die nicht nachgeahmt werden kann.

if (typeof Object.create != 'function') { 
    (function() { 
    var F = function() {}; 
    Object.create = function (o) { 
     if (arguments.length > 1) { throw Error('Second argument not supported');} 
     if (o === null) { throw Error('Cannot set a null [[Prototype]]');} 
     if (typeof o != 'object') { throw TypeError('Argument must be an object');} 
     F.prototype = o; 
     return new F; 
    }; 
    })(); 
} 

Wie auch immer, es sorgfältig verwenden:

Die folgende wäre eine sichere Version der Crockford's Object.create shim sein.

2

Für das, was es wert ist,

Object.defineProperty Werke in IE8 und FF4.

Dies bedeutet, es lohnt sich, Sniff und Feature zu implementieren, wo es nützlich ist zu sehen, wie Sie hoffen, dass das Upgrade von IE 6/7 zu 8/9 in den nächsten Jahren auftreten wird.

Eine andere Sache, von vorsichtig zu sein, ist, dass die DontEnum Eigenschaft einen Fehler in JScript

hat, wird Sie haben rund um die Art und Weise Sie die DontEnum Eigenschaft in IE verwenden, um zu arbeiten.

[Bearbeiten]:

Hier Dokumentation für Internet explorer und ein Link zur ES5 specification (Seite 122, 15.2.3.6)

+0

Das ist gut zu wissen, dass es in IE8 ist, ich sah einen Blick, was eine Implementierung hätte sein können. Meine Frage ist also immer noch eine veröffentlichte Implementierung von defineProperty? – Drew

+0

Es gibt keine solche Implementierung für ie6/7, fürchte ich. – Raynos

+4

@Drew: 'Object.defineProperty' funktioniert * teilweise * IE8, Sie können es nur auf * DOM Elements * verwenden. Ich habe eine [Antwort] (http://stackoverflow.com/questions/3830800/object-defineproperty-in-5/3844768#3844768), die kurz gesagt: Sie können nicht verlassen. Eigenschaftsattribute können nicht in ECMAScript 3-basierten Implementierungen definiert werden. – CMS

4

Wenn Sie eine gute DefineProperty() -Implementierung wollen, werfen Sie einen Blick auf https://github.com/kriskowal/es5-shim

Leider kann man nicht konfigurierbar machen Aufzählung in einer ES3 Umgebung. Mit diesem Shim können Sie die API in jeder Umgebung aufrufen, die Eigenschaften sind jedoch unter ES3 weiterhin aufzählbar.

+0

Das ist wirklich cool, danke – Drew