2

私はCodeyearの仲間ですが、残念ながらプロトタイプオブジェクトの概念は説明されていません。グーグルで検索してチュートリアルを見つけました。学習した後、私の理解では、プロトタイプオブジェクトの継承を使用してメモリを節約し、オブジェクト間で共通のプロパティを共有しているとのことです。私は正しいですか?はいの場合、以下のコードは悪い習慣だと思わないでください。車のコンストラクターはすでに価格、速度、およびgetPriceを定義しているので、継承の概念を使用しているので、なぜ同じことを再度定義する必要があるのですか。説明してください 。以下はコードです。

function Car( listedPrice ) {
    var price = listedPrice;
    this.speed = 0;

    this.getPrice = function() {
        return price;
    };
}

Car.prototype.accelerate = function() {
    this.speed += 10;
};

function ElectricCar( listedPrice ) {
    var price = listedPrice;
    this.speed = 0;

    this.getPrice = function() {
        return price;
    };
}

ElectricCar.prototype = new Car(); // Please also explain why car constructor 
                                   // is not thowing error since we are not passing
                                   // listedPrice parameter

myElectricCar = new ElectricCar(500);

console.log(myElectricCar instanceof Car);
4

2 に答える 2

3

コンストラクターとプロトタイプは2つの別個の概念です。でプロトタイプの継承を適用​​するとElectricCar.prototype = new Car();、コンストラクター自体ではなく、オブジェクトとそのプロトタイプで定義されたメソッドのみが継承されます。

console.log()これがいくつかのクイックコールでどのように機能するかを実際に確認できます。

console.log(ElectricCar);
console.log(ElectricCar.prototype);
console.log(ElectricCar.prototype.__proto__);

これは次を返します:

[Function: ElectricCar]
{ speed: 0, getPrice: [Function] }
{ accelerate: [Function] }

最初の行はコンストラクターです。

2つ目は、上記で設定した実際のプロトタイプElectricCar.prototype = new Car();です。Carとのコンストラクターで、this.speedとが設定されたことを思い出してください。これは、とthis.getPriceの値を説明しています。ElectricCar.prototype.speedElectricCar.prototype.getPrice

おそらく最も明確でないのは、最後の行であるElectricCar.prototype.__proto__。これが試作品の試作品です。Carオブジェクトには、定義されたprototypeオブジェクトがあります。accelerateこのプロトタイプはElectricCar、その内部__proto__プロパティののプロトタイプにコピーされます。これはプロトタイプチェーンと呼ばれます。

コンストラクターはプロトタイプの一部ではなく、プロトタイプは継承しているすべてであるため、のコンストラクターはCarコピーされてに貼り付けられていElectricCarます。ご指摘のとおり、これを行うには間違いなくよりクリーンな方法があります。別の方法は次のとおりです。

function ElectricCar( listedPrice ) {
    Car.apply(this, arguments);
}

ElectricCar.prototype = new Car();

詳細については、を参照applyしてください。

最後の質問(なぜエラーをスローしないのかnew Car())については、他の回答が言うように、それはJavaScriptがどのように機能するかということです。関数に指定する引数がパラメーターよりも少ない場合、未設定の(いわば)パラメーターはすべてに設定されundefinedます。実証するために:

function returnMe(a) {
    return a;
}

console.log(returnMe(5));
console.log(returnMe(2+2));
console.log(returnMe());
console.log(returnMe(undefined));

これは戻ります:

5
4
undefined
undefined

ご覧のとおりundefined、実際には(のように)渡すことができる変数ですreturnMe(undefined)。詳細については、を参照してくださいundefined

于 2012-06-09T15:16:30.750 に答える
0

getPricepriceこれは、外部スコープでvarのクロージャを作成し、この関数だけがアクセスできるpriceプライベートメンバーを、インスタンスごとに個別に効果的に作成する方法です。

JavaScriptで関数に引数を指定することは必須ではないため、コンストラクターはエラーをスローしません。必要なだけ指定し、名前付き引数がある限り、指定したリストから最初にその名前に割り当てられます。

于 2012-06-09T15:01:31.947 に答える