0

私は 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追加することでメソッドが正しく機能しますが、そうではありません。div<span id="test"></span>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実際、より正しいアプローチですか?もしそうなら、正しく動作するようにどのように設定する必要がありますか?

助けてくれてありがとう!!!

4

1 に答える 1

0

これらの例はどちらも「正しい」ものではありません。プロトタイプ メソッドでは、既にアタッチされているオブジェクトの新しいコピーをインスタンス化しようとするべきではありません。あなたがする必要があるのはこれだけです:

HTMLElement.prototype.bar = function() {
    let div = document.createElement('div');
    div.innerHTML = 'fooRenderer';
    this.appendChild(div);
}

最初の例foo.parentElementは、カスタム作成されたオブジェクトではなく、有効なネイティブ HTMLElement であるためのみ機能します。

カスタム オブジェクトのような「ネイティブ」ブラウザ メソッドを呼び出せない理由については、この回答を参照してください。appendChild

于 2016-10-31T18:47:10.143 に答える