1

プロトタイプ継承の理解が不十分なため、行き詰っています。プロトタイプ継承とは何か、どのように実装されているのか知りたいです。

簡単な例を1つ示していただけますか?
どんな助けでも大歓迎です。

4

3 に答える 3

1

その核心に

オブジェクトがあり、プロパティを検索したいとします。ここで、プロパティが存在しないと想像してください。別のオブジェクトでそのプロパティの検索を自動的に続行できるとしたら? それが基本的にプロトタイプ継承です。


どうやってそれをするのですか?

したがって、唯一の問題は、オブジェクト間のこの関係をどのように作成するかです。まあ、それは奇妙な部分です。

主な歴史的な方法から始めましょう。つまり、関数を使用しています。

最初に注意すべきことは、JavaScript の関数はそれ自体がオブジェクトであるということです。独自のプロパティを持つことができ、プロトタイプの継承を使用して他のプロパティにアクセスできます。

それでは、関数を作成することから始めましょう。

function Foo() {
    // our function
}

これで、 という名前の関数ができましFooた。新しい関数は、prototype作成時に名前が付けられたプロパティを自動的に取得します。そのプロパティは (ほぼ) 空のオブジェクトを参照します。

console.log(typeof Foo.prototype); // object

なぜそのプロパティとオブジェクトが存在するのですか? これらは、JavaScript が上記で説明したオブジェクト間の関係を形成する奇妙な方法をサポートするために存在します。

基本的に、Foo.prototypeオブジェクトは、オブジェクトの新しいプロパティを探すときに「バックアップ」オブジェクトとして使用するものです。しかし、使用したいオブジェクトとオブジェクトの間に特別な関係はまだ形成されていませんFoo.prototype


それを機能させる

これを行うには、実際にnew演算子を使用して関数を呼び出します。

var my_object = new Foo();

そして、そこに行きます。これmy_objectが新しい空のオブジェクトです。しかし、その「プロトタイプチェーン」には、そのプロパティからFoo離れた機能からぶら下がっているオブジェクトがあります。.prototypeつまり、 でプロパティを検索するときにmy_object、プロパティが存在しない場合は、Foo.prototypeオブジェクトの検索を続行します。


実際に見る

問題は、 に役立つと思われるものを何も追加していないことですFoo.prototype。しかし、実際にはそのオブジェクトには 1 つのプロパティがあります。Fooこのプロパティは、関数を作成したときにも自動的に作成されたもので、.constructorプロパティです。

そのプロパティは何を参照していますか? 関数への参照がありFooます。言い換えると:

Foo.prototype.constructor === Foo; // true

よし、もし私たちのmy_objectが空で、その上のプロパティを探しているときにmy_object存在しない場合、それはFoo.prototypeオブジェクトの検索を続けFoo.prototype.constructorますmy_object

my_object.constructor === Foo; // true

そして、それは機能します。my_objectは という名前のプロパティを持っていなかったため、継承constructor元のオブジェクトである を検索し続けました。これはFoo.prototype、ご存知の.constructorように、関数を参照するプロパティを持っていFooます。


コードのカスタマイズ

素晴らしい。しかし、コード内でより便利な他のプロパティをどのように設定すればよいでしょうか? に追加するだけFoo.prototypeです。my_objectオブジェクトがそれらを直接所有していない場合、これらのプロパティを見つけることができます。

// give a custom property to `Foo.prototype`
Foo.prototype.bar = "foobar";

// see if we can access that property on your object
my_object.bar === "foobar"; // true

案の定、うまくいきました。それでは、そのプロパティFooにもアクセスできる新しいオブジェクトを作成できるかどうか見てみましょう。.bar

var another_object = new Foo();

another_object.bar === "foobar"; // true

繰り返しますが、機能します。これはFoo、キーワードを使用して呼び出して作成されたすべてのオブジェクトnewのプロトタイプ チェーンにFoo.prototypeオブジェクトが含まれるためです。つまり、Foo.prototypeはから作成されたすべてのインスタンスで共有Fooされます。

したがって、Foo.prototype.barプロパティを変更すると、作成した両方のオブジェクトに反映されます。

Foo.prototype.bar = "raboof";

my_object.bar === "raboof";      // true
another_object.bar === "raboof"; // true

したがって、両方のオブジェクトが、「プロトタイプチェーン」内の次のオブジェクトに検索を渡すことによって、持っていないプロパティを探しているだけであることがわかります。これは、Foo関数からぶら下がっている奇妙なオブジェクトです... Foo.prototype.


学ぶべきことはまだあります

このオブジェクトの関係をセットアップする新しい方法がありますが、これは元の方法であり、その奇妙さにもかかわらず、おそらく最初に理解する必要があります。

于 2013-06-27T14:11:53.063 に答える
0

これは私がそれを理解する方法です:

これはコンストラクターと見なすことができます

var Thing = function(){
    this.method1 = function(){
        alert( "method 1" );
    }
}

これはその例です

var a_thing = new Thing();

a_thing.method1();

これで、コンストラクターのプロトタイプに何かを追加すると、既にインスタンス化されたオブジェクトで自動的に使用できるようになります。

Thing.prototype.method2 = function(){
    alert( "method2" );
}

a_thing.method2();

お役に立てれば。

于 2013-06-27T13:40:30.030 に答える
-1

これは私が考えることができる最も単純な例です。
ピザ クラスは、次の行を使用して circle から継承します。

pizza.prototype = new circle();

完全な例:

<html>
<head>
    <script>
        // base class
        function circle(radius){
            this.radius = radius;

            this.getArea = function ()
            {
                return (this.radius * this.radius) * Math.PI;
            };

            this.foo = function ()
            {
                return "circle foo";
            };

            return true;
        }

        // child class
        function pizza(flavour, radius){
            circle.call(this, radius);
            this.flavour = flavour;

            this.foo = function ()
            {
                return "pizza foo";
            };
            return true;
        }

        // Inheritance
        pizza.prototype = new circle();

        function Go(){
            // Instancing new object
            var myCircle = new circle(8);
            var myPizza = new pizza("Onion", 5);

            // Calling property
            var pizza_area = myPizza.getArea();

            // Calling override foo function
            var foo = myPizza.foo();

            // Calling foo base class
            var base = pizza.prototype.foo.call(myPizza);
            //Line.prototype.someFunction.call(myLine);

            var isBase = myCircle instanceof pizza;
            isBase = myPizza instanceof pizza;
        }

    </script>    
</head>
<body onload="Go();">

</body>
</html>
于 2013-06-27T13:38:16.327 に答える