Suche…
Standard-Funktionsprototyp
Beginnen Sie mit der Definition einer Foo
Funktion, die wir als Konstruktor verwenden.
function Foo (){}
Durch die Bearbeitung von Foo.prototype
können wir Eigenschaften und Methoden definieren, die von allen Instanzen von Foo
.
Foo.prototype.bar = function() {
return 'I am bar';
};
Wir können dann eine Instanz mit dem new
Schlüsselwort erstellen und die Methode aufrufen.
var foo = new Foo();
console.log(foo.bar()); // logs `I am bar`
Unterschied zwischen Object.key und Object.prototype.key
Im Gegensatz zu Sprachen wie Python werden statische Eigenschaften der Konstruktorfunktion nicht an Instanzen vererbt. Instanzen erben nur von ihrem Prototyp, der vom Prototyp des übergeordneten Typs erbt. Statische Eigenschaften werden niemals vererbt.
function Foo() {};
Foo.style = 'bold';
var foo = new Foo();
console.log(Foo.style); // 'bold'
console.log(foo.style); // undefined
Foo.prototype.style = 'italic';
console.log(Foo.style); // 'bold'
console.log(foo.style); // 'italic'
Neues Objekt vom Prototyp
In JavaScript kann jedes Objekt der Prototyp eines anderen Objekts sein. Wenn ein Objekt als Prototyp eines anderen Objekts erstellt wird, erbt es alle Eigenschaften des übergeordneten Objekts.
var proto = { foo: "foo", bar: () => this.foo };
var obj = Object.create(proto);
console.log(obj.foo);
console.log(obj.bar());
Konsolenausgabe:
> "foo"
> "foo"
HINWEIS Object.create
von ECMAScript verfügbar ist 5, aber hier ist ein polyfill , wenn Sie für ECMAScript unterstützen müssen 3
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
Object.create ()
Die Object.create () -Methode erstellt ein neues Objekt mit dem angegebenen Prototypobjekt und den angegebenen Eigenschaften.
Syntax: Object.create(proto[, propertiesObject])
Parameter :
- proto (Das Objekt, das der Prototyp des neu erstellten Objekts sein soll.)
- propertiesObject (optional. Falls angegeben und nicht undefiniert, gibt ein Objekt an, dessen eigene Eigenschaften über die Aufzählungszeichen definiert sind (dh die Eigenschaften, die für sich selbst definiert sind und nicht die Eigenschaften, die entlang ihrer Prototypkette aufgezählt werden können) Eigenschaftsdeskriptoren, die dem neu erstellten Objekt mit dem entsprechenden Objekt hinzugefügt werden Eigenschaftennamen Diese Eigenschaften entsprechen dem zweiten Argument von Object.defineProperties ().)
Rückgabewert
Ein neues Objekt mit dem angegebenen Prototypobjekt und den angegebenen Eigenschaften.
Ausnahmen
Eine TypeError- Ausnahme, wenn der Protoparameter nicht null oder ein Objekt ist.
Prototypische Vererbung
Angenommen, wir haben ein einfaches Objekt namens prototype
:
var prototype = { foo: 'foo', bar: function () { return this.foo; } };
Jetzt wollen wir ein anderes Objekt namens obj
, die von erbt prototype
, das ist das gleiche wie das zu sagen prototype
ist der Prototyp von obj
var obj = Object.create(prototype);
Nun stehen alle Eigenschaften und Methoden des prototype
für obj
zur obj
console.log(obj.foo);
console.log(obj.bar());
Konsolenausgabe
"foo"
"foo"
Die prototypische Vererbung erfolgt intern durch Objektreferenzen und Objekte sind vollständig veränderbar. Das heißt, jede Änderung, die Sie an einem Prototyp vornehmen, wirkt sich sofort auf alle anderen Objekte aus, deren Prototyp Prototyp ist.
prototype.foo = "bar";
console.log(obj.foo);
Konsolenausgabe
"bar"
Object.prototype
ist der Prototyp jedes Objekts. Es wird daher dringend empfohlen, sich nicht damit zu beschäftigen, insbesondere wenn Sie eine Bibliothek eines Drittanbieters verwenden.
Object.prototype.breakingLibraries = 'foo';
console.log(obj.breakingLibraries);
console.log(prototype.breakingLibraries);
Konsolenausgabe
"foo"
"foo"
Fun Tatsache , ich habe die Browser - Konsole verwendet , um diese Beispiele zu machen und diese Seite gebrochen , indem fügte hinzu , dass breakingLibraries
Eigenschaft.
Pseudo-klassisches Erbe
Es ist eine Emulation der klassischen Vererbung mit prototypischer Vererbung, die zeigt, wie leistungsfähig Prototypen sind. Es wurde gemacht, um die Sprache für Programmierer, die aus anderen Sprachen kommen, attraktiver zu machen.
WICHTIGER HINWEIS : Seit ES6 ist die Verwendung einer pseudo-klassischen Vererbung nicht sinnvoll, da die Sprache herkömmliche Klassen simuliert. Wenn Sie ES6 nicht verwenden, sollten Sie dies tun. Wenn Sie immer noch das klassische Vererbungsmuster verwenden möchten und sich in einer Umgebung mit ECMAScript 5 oder niedriger befinden, ist Pseudoklassik die beste Wahl.
Eine "Klasse" ist nur eine Funktion, die mit dem new
Operanden aufgerufen wird und als Konstruktor verwendet wird.
function Foo(id, name) {
this.id = id;
this.name = name;
}
var foo = new Foo(1, 'foo');
console.log(foo.id);
Konsolenausgabe
1
foo ist eine Instanz von Foo. Die JavaScript-Codierungskonvention besagt, dass eine Funktion, die mit einem Großbuchstaben beginnt, als Konstruktor (mit dem new
Operanden) aufgerufen werden kann.
Um Eigenschaften oder Methoden zur "Klasse" hinzuzufügen, müssen Sie sie ihrem Prototyp hinzufügen, der sich in der prototype
des Konstruktors befindet.
Foo.prototype.bar = 'bar';
console.log(foo.bar);
Konsolenausgabe
Bar
Tatsächlich erstellt Foo als Konstruktor nur Objekte mit dem Prototyp Foo.prototype
.
Sie können für jedes Objekt einen Verweis auf seinen Konstruktor finden
console.log(foo.constructor);
Funktion Foo (ID, Name) {...
console.log({ }.constructor);
Funktion Object () {[native code]}
Prüfen Sie auch, ob ein Objekt eine Instanz einer bestimmten Klasse mit dem Operator instanceof
console.log(foo instanceof Foo);
wahr
console.log(foo instaceof Object);
wahr
Festlegen eines Prototyps eines Objekts
Mit ES5 + kann die Object.create
Funktion verwendet werden, um ein Objekt mit einem beliebigen anderen Objekt als Prototyp zu erstellen.
const anyObj = {
hello() {
console.log(`this.foo is ${this.foo}`);
},
};
let objWithProto = Object.create(anyObj);
objWithProto.foo = 'bar';
objWithProto.hello(); // "this.foo is bar"
Um ein Objekt explizit ohne Prototyp zu erstellen, verwenden Sie null
als Prototyp. Dies bedeutet, dass das Objekt auch nicht von Object.prototype
erbt. Object.prototype
ist nützlich für Objekte, die für Wörterbücher zur Existenzprüfung verwendet werden, z
let objInheritingObject = {};
let objInheritingNull = Object.create(null);
'toString' in objInheritingObject; // true
'toString' in objInheritingNull ; // false
In ES6 kann der Prototyp eines vorhandenen Objekts beispielsweise mit Object.setPrototypeOf
geändert werden
let obj = Object.create({foo: 'foo'});
obj = Object.setPrototypeOf(obj, {bar: 'bar'});
obj.foo; // undefined
obj.bar; // "bar"
Dies kann fast überall geschehen, einschließlich für this
Objekt oder einen Konstruktor.
Hinweis: Dieser Vorgang ist in aktuellen Browsern sehr langsam und sollte sparsam verwendet werden. Versuchen Sie, das Objekt mit dem gewünschten Prototyp zu erstellen.
Vor ES5 bestand die einzige Möglichkeit zum Erstellen eines Objekts mit einem manuell definierten Prototyp darin, es beispielsweise mit new
zu erstellen
var proto = {fizz: 'buzz'};
function ConstructMyObj() {}
ConstructMyObj.prototype = proto;
var objWithProto = new ConstructMyObj();
objWithProto.fizz; // "buzz"
Dieses Verhalten ist nah genug an Object.create
sodass Sie eine Polyfill schreiben können.