Object.create ist in einigen Browsern noch nicht Standard, z.B. IE8, Opera v11.5, Konq 4.3 haben es nicht. Sie können Douglas Crockfords Version von Object.create für diese Browser verwenden, aber diese enthält nicht den zweiten Parameter "Initialisierungsobjekt", der in der Antwort von CMS verwendet wird.
Für browserübergreifenden Code ist eine Möglichkeit, die Objektinitialisierung in der Zwischenzeit zu erhalten, die Anpassung von Crockfords Object.create. Hier ist eine Methode:-
Object.build = function(o) {
var initArgs = Array.prototype.slice.call(arguments,1)
function F() {
if((typeof o.init === 'function') && initArgs.length) {
o.init.apply(this,initArgs)
}
}
F.prototype = o
return new F()
}
Dadurch wird die prototypische Vererbung nach Crockford beibehalten, und es wird auch geprüft, ob eine init-Methode im Objekt vorhanden ist, die dann mit Ihren Parametern ausgeführt wird, z. B. new man('John','Smith'). Ihr Code wird dann:-
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}} // For example
var userB = {
init: function(nameParam) {
this.id = MY_GLOBAL.nextId();
this.name = nameParam;
},
sayHello: function() {
console.log('Hello '+ this.name);
}
};
var bob = Object.build(userB, 'Bob'); // Different from your code
bob.sayHello();
So erbt bob die sayHello-Methode und hat nun eigene Eigenschaften id=1 und name='Bob'. Diese Eigenschaften sind natürlich sowohl beschreibbar als auch aufzählbar. Dies ist auch eine viel einfachere Art der Initialisierung als ECMA Object.create, vor allem, wenn Sie sich keine Gedanken über die Attribute writable, enumerable und configurable machen.
Für die Initialisierung ohne init-Methode könnte die folgende Crockford-Mod verwendet werden:-
Object.gen = function(o) {
var makeArgs = arguments
function F() {
var prop, i=1, arg, val
for(prop in o) {
if(!o.hasOwnProperty(prop)) continue
val = o[prop]
arg = makeArgs[i++]
if(typeof arg === 'undefined') break
this[prop] = arg
}
}
F.prototype = o
return new F()
}
Dies füllt die eigenen Eigenschaften von userB in der Reihenfolge, in der sie definiert sind, mit den Object.gen-Parametern von links nach rechts nach dem userB-Parameter. Es wird die for(prop in o) Schleife verwendet, so dass nach ECMA-Standards nicht garantiert werden kann, dass die Reihenfolge der Eigenschaftsaufzählung mit der Reihenfolge der Eigenschaftsdefinition übereinstimmt. Mehrere Codebeispiele, die auf (4) gängigen Browsern getestet wurden, zeigen jedoch, dass sie gleich sind, sofern der hasOwnProperty-Filter verwendet wird, und manchmal auch, wenn dies nicht der Fall ist.
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}; // For example
var userB = {
name: null,
id: null,
sayHello: function() {
console.log('Hello '+ this.name);
}
}
var bob = Object.gen(userB, 'Bob', MY_GLOBAL.nextId());
Etwas einfacher würde ich sagen als Object.build, da userB keine init-Methode benötigt. Außerdem ist userB kein spezieller Konstruktor, sondern sieht aus wie ein normales Singleton-Objekt. Mit dieser Methode können Sie also aus normalen einfachen Objekten konstruieren und initialisieren.