4

2 つのコンストラクター関数があるとします。

var Person = function(xx,xx,xxx,xxxxxxx) {
  //Person initialization
}

var Man = function(xx,xx,xxx,xxx) {
  //Man initialization
}

そして、マンはパーソンから拡張したい。

私が考えたことは次のとおりです。

作成された Man オブジェクトが与えられた場合:

var m=new Man("xx",....);

1) のプロパティmがアクセスされると、 で検索されMan.prototypeます。

2) 見つからない場合は、 で見つける必要がありますMan.prototype.__prop__

だから私がやっていることは、Man.prototype.__prop__リンク先を作ることPerson.prototypeです。

私はこれが一般的な方法であることを知っています:

function inherit(superClass) {
    function F() {}
    F.prototype = superClass.prototype;
    return new F;
}
Man.prototype=inherit(Person);

しかし、私がこれを試すと:

Man.prototype.prototype=Person.prototype.

うまくいかないのはなぜですか?

4

3 に答える 3

6

のインスタンスを、そのコンストラクターに追加されたプロパティを保持Manする のインスタンスに実際にリンクしたいようですPerson。この場合、次のようなものが本当に必要になる場合があります。

function Person(a, b) {
    this.a = a;
    this.b = b;
}

function Man() {}
Man.prototype = new Person("val1", "val2");

var m = new Man();
console.log(m.a);

...印刷しval1ます。

追加のとりとめのない

の目的は、指定されたスーパークラスのinherit関数から (明示的に を使用せずに) オブジェクトを作成することです。これはまさにそれが行うことです。したがって、次のように表示されます。prototypenewstring

function Person() {}
Person.prototype.test = "string";

function Man() {}

function inherit(superClass) {
    function F() {}
    F.prototype = superClass.prototype;
    return new F;
}

var t = inherit(Person);
console.log(t.test);

しかし、通常は、返されたオブジェクトを別の関数のプロトタイプに割り当てたいとします:

Man.prototype = inherit(Person);

var m = new Man();
console.log(m.test);

...そのため、m.testも出力stringされます。これは、 を使用して作成されたオブジェクトManが にリンクされていることを意味しPersonますprototype)。

Man.prototype.prototypeであることに注意してくださいundefined-- これは重要な部分です -- また無意味です。関数にはプロトタイプがあります。他のオブジェクト ( などMan.prototype) にはありません。プロパティは、prototype他のコンテキストでは魔法ではありません。ランダム オブジェクトのprototypeプロパティに値を代入しても、特別なことは何も行われません。それは単なる別のプロパティです。

から返されたものは、その経由でinheritリンクされており、のインスタンスに追加されたプロパティにはアクセスできないことにも注意してください。PersonprototypePerson

于 2012-07-02T07:20:28.323 に答える
3

私のやり方(あなたの例に関して):

var Person = function () {
}

// Define "Person" methods

var Man = function () {
}

Man.prototype = new Person();

// Define "Man" methods

アップデート

パラメーターを持つコンストラクターについて:それを理解するのに本当に役立つこのSOの質問を見つけました(2番目の答え、最初の部分):JavaScriptの継承:コンストラクターに引数がある場合

于 2012-07-02T06:29:18.473 に答える
0

それを行うための一般的な方法がかなりあります。私はそれらの3つを提供します:

1.) Function オブジェクトをコンストラクタとして、また継承された新しいオブジェクトのプロトタイプ オブジェクトとして使用する。実装は次のようになります。

var person = {
    toString : function() {
        return this.firstName + ' ' + this.lastName;
    }
}


function extend(constructor, obj) {
    var newObj = Object.create(constructor);
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            newObj[prop] = obj[prop];
        }
    }
    return newObj;
}

var man = extend(person, 
    {
        sex: "male", 
        age: "22"
    });

var name = extend(man, 
    {
        firstName: "Simo",
        lastName: "Endre"
    });

name.man;
name.toString();

2.) この場合、C# や Java などの言語で従来の継承をシミュレートするためのコンストラクターとして Function オブジェクトを使用します。オブジェクトのプロトタイプ プロパティはコンストラクタの役割で使用され、新しく作成されたオブジェクトはオブジェクト プロトタイプ ルートからすべてのプロパティを継承します。この場合、オブジェクトのプロトタイプには 1 種類の拡張ロールしかなく、効果的な実装は関数メソッドで行われます。

var Person = function(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Person.prototype.toString = function() {
    return this.firstName + ' ' + this.lastName;
}

function inherit(func) {
    // passing function arguments into an array except the first one which is the function object itself
    var args = Array.prototype.slice.call(arguments, 1);

    // invoke the constructor passing the new Object and the rest of the arguments
    var obj = Object.create(func.prototype);
    func.apply(obj, args);        

    //return the new object
    return obj;   
}

var man = inherit(Person, "Simo", "Endre");
man.toString();

3.) よく知られた継承モデル:

function extend(o) {
  function F() {}

  // We'll set the newly created function prototype property to the object. 
  //This act as a constructor.
  F.prototype = o;

  // Using the `new` operator we'll get a new object whose prototype is o.
  return new F();
};
于 2012-07-02T11:18:12.297 に答える