Ich versuche, mehr über Javascript zu lernen und ein wenig in die Prototyp-Kette zu graben. Ich wollte eine kleine Erweiterung für ein HTMLElement erstellen, als ich auf dieses Problem stieß. Die Art, wie ich verstehe Object.create
ist, dass das Objekt, das an es übergeben wird, verwendet wird, um den Kontext für das neue Objekt zu erstellen, und dass die erste Verknüpfung in der Prototypkette des neu erstellten Objekts auf das Objekt verweist Object.create
Methode. In diesem Fall schien mir die Methode der Erweiterung, die in der folgenden bar
-Methode verwendet wird, der richtige Ansatz zu sein, da dieses neu erstellte Objekt sein HTMLElement als Kontext erhalten würde.Warum wird die Prototypkette anders ausgeführt?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<span id="test"></span>
<script>
HTMLElement.prototype.foo = function() {
let foo = Object.create(null);
foo.parentElement = this;
foo.parentElement.appendChild(document.createElement('div'));
}
HTMLElement.prototype.bar = function() {
let fooRenderer = Object.create(this);
fooRenderer.appendChild(document.createElement('div'));
}
document.getElementById('test').foo();
document.getElementById('test').bar();
</script>
</body>
</html>
Was allerdings passiert, ist, dass die foo
Methode korrekt durch ein neues div
geordnetes Element zu <span id="test"></span>
anhängt, aber bar
funktioniert nicht.
Wenn ich die Entwickler-Tools in meinem Browser öffnen und versuchen, die Prototyp-Ketten der beiden Objekte zu folgen, die appendChild
auf sie aufgerufen haben, sehen sie fast identisch:
foo Object
.parentElement <span#test2>
.__proto__ HTMLSpanElementPrototype
.__proto__ HTMLElementPrototype
.__proto__ ElementPrototype
.__proto__ NodePrototype
.appendChild
.__proto__ EventTargetPrototype
.__proto__ Object
.__proto__
get
set
fooRenderer Object
.__proto__ <span#test2>
.__proto__ HTMLSpanElementPrototype
.__proto__ HTMLElementPrototype
.__proto__ ElementPrototype
.__proto__ NodePrototype
.appendChild
.__proto__ EventTargetPrototype
.__proto__ Object
.__proto__
get
set
ich geschaffen habe eine jsFiddle mit Dieses Beispiel.
Kann mir bitte jemand erklären, warum bar
nicht funktioniert? Ist bar
in der Tat der richtige Ansatz? Wenn ja, wie sollte es eingerichtet werden, um ordnungsgemäß zu funktionieren?
Vielen Dank im Voraus für jede Hilfe !!!
Obwohl in Ihrer Prototyp-Kette ein 'HTMLSpanElement' vorhanden ist, ist Ihr' fooRenderer'-Objekt nur ein Objekt und kein echter DOM-Knoten. – Bergi
@Bergi Danke, aber ich bin mir nicht sicher, was du sagst. Wollen Sie damit sagen, dass JavaScript die Prototypkette tatsächlich durchläuft und eine Methode 'appendChild' findet, aber nicht ausführen kann, weil es an einem Punkt und nicht an einem DOM-Knoten ausgeführt wird? – peinearydevelopment
Ja, genau (Sie sollten einen Fehler bekommen, der so etwas besagt). Es wird versucht, für ein Objekt aufgerufen zu werden, das die Knotenmethoden erbt, aber nicht als Knoten initialisiert wurde (und auch kein * natives * DOM-Knotenobjekt ist). – Bergi