私はJavascriptについてもっと学び、プロトタイプチェーンに少し掘り下げようとしています。私はこの問題に遭遇したときにHTMLElement用の小さなエクステンションを作成したかったのです。プロトタイプチェーンが異なる方法で実行されるのはなぜですか?
Object.create
私が理解している方法は、それに渡されるオブジェクトが新しいオブジェクトのコンテキストを作成するために使用され、新しく作成されたオブジェクトのプロトタイプチェーンの最初のリンクが、 Object.create
方法。その場合、以下のbar
メソッドで使用されている拡張メソッドは、この新しく作成されたオブジェクトにそのHTMLElementがそのコンテキストとして与えられるため、私にとって正しいアプローチであるように見えました。
<!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>
何かかわらず起こることはfoo
方法は<span id="test"></span>
に新しいdiv
子要素を追加することで正常に動作しますが、bar
ないということです。
私は私のブラウザで開発ツールを開いて、その上で呼び出さappendChild
を持っている2つのオブジェクトのプロトタイプチェーンを追跡しようとすると、彼らはほとんど同じに見える:
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
私はとjsFiddleを作成しましたこの例。
誰かが私に理由を説明してもらえますか?bar
は機能していませんか?実際にbar
はより正しいアプローチですか?もしそうなら、どのように正しく動作するようにセットアップする必要がありますか?
ご協力いただきありがとうございます!
プロトタイプチェーンに 'HTMLSpanElement'がありますが、' fooRenderer'オブジェクトは単なるオブジェクトであり、実際のDOMノードではありません。 – Bergi
@Bergiありがとうございますが、私はあなたが何を言っているのか分かりません。あなたはjavascriptが実際にプロトタイプチェーンをたどって 'appendChild'メソッドを見つけるのですが、その時点でDOMノードではなくオブジェクト上で実行されているので、実行できません。 – peinearydevelopment
はい、まさにそのようなことを述べているエラーが発生しているはずです。ノードメソッドを継承するが、ノードとして初期化されていない(ネイティブ* DOMノードオブジェクトでもない)オブジェクトで呼び出されるように試みられます。 – Bergi