2016-04-02 6 views
1

JavaScriptの継承で見つかったサンプルを実装しようとしていますが、子オブジェクトが期待どおりに構築されていないようです。次の例では、jillインスタンスを作成してもJillオブジェクトは返されず、子または親のメソッドを呼び出すことはできません。JavaScriptコンストラクタは実行されていませんか?

あなたが誤ってオブジェクトを開始している
var Person = function() { 
    this.name = "unnamed"; 
} 
Person.prototype.sayName = function() { 
    console.log("My name is " + this.name); 
} 
var Jill = function() { 
    var jill = function() { 
    Person.call(this); 
    this.name = "Jill"; 
    }; 
    jill.prototype = Object.create(Person.prototype); 
    jill.prototype.constructor = jill; 
    jill.prototype.expressJoy = function() { 
    console.log("Huray!"); 
    }; 
    return jill; 
} 
var jill = new Jill(); 
console.log(jill instanceof Jill); // false 
jill.expressJoy(); // error, is not a function 
jill.sayName(); // error, seen if comment out previous line 
+1

'jill'は実際のコンストラクタです。なぜあなたは 'Jill'関数でそれをラップしたのか分かりません。これはIIFEであるはずだったのでしょうか? – Bergi

+0

うん、@Bergi - あなたが正しい考えを持っていたように見える。 – scader

答えて

2

を動作するはずです通常の関数、コンストラクタのようなものではありません。以下に示すように
はあなたのコードを変更し :

var Jill = (function() { 
    function Jill() { 
     Person.call(this); 
     this.name = "Jill"; 
    }; 
    Jill.prototype = Object.create(Person.prototype); 
    Jill.prototype.constructor = Jill; 
    Jill.prototype.expressJoy = function() { 
     console.log("Huray!"); 
    }; 
    return Jill; 
})(); 

var jill = new Jill(); 
console.log(jill); // Jill {name: "Jill"} 
console.log(jill instanceof Jill); // true 
jill.expressJoy(); // Huray! 
jill.sayName(); // My name is Jill 

を今Jillは、あなたが期待通りにオブジェクトを生成する「本当の」コンストラクタです。 (良い例では、コンストラクタ名は大文字で始まります)

+0

ありがとう、私は偶然、この例を例から逃しました。 – scader

+0

@scader、あなたは歓迎です – RomanPerekhrest

+0

@scader、この方法では、各オブジェクトの作成に常に 'new'を使用する必要があります。あなたがJillに 'new jill()'を返すと(私の例のように)、 'new'を逃すことや引き起こす可能性のある問題について心配する必要はありません。 _Every_Jill()への呼び出しは、新しいオブジェクトを返します。 – Andy

1

var jill = Jill(); 
var obj = new jill(); 

機能Jillは機能referenceないobjectを返しています。また、関数参照を返すことの上で、あなたの要求に応じてobjectを作成する必要があります。新しいインスタンスを作成する関数を呼び出すための内部機能で

1)return new jill();、その後、

2)var jill = Jill();

あなたがする必要があなたのコードで
0

DEMO

これは、あまり複雑な方法です。

function Person() { 
    this.name = "unnamed"; 
} 

Person.prototype.sayName = function() { 
    console.log("My name is " + this.name); 
} 

function Jill() { 
    Person.call(this); 
    this.name = "Jill"; 
} 
Jill.prototype = Object.create(Person.prototype); 
Jill.prototype.constructor = Jill; 
Jill.prototype.expressJoy = function() { 
    console.log("Huray!"); 
}; 

var jill = new Jill(); 

DEMO

1

これは修正されたコードで、詳細な説明を編集します:

JSBIN Example

// This is your Person class, all "people" will inherit from this object 

var Person = function() { 
    this.name = "unnamed"; 
}; 
// add the sayName function to this prototype 
Person.prototype.sayName = function() { 
    console.log("My name is " + this.name); 
}; 

// now we make a 'Jill' constructor; 
var Jill = function() { 
    Person.call(this); // bind this (Jill) to Person 
    this.name = 'jill'; 
}; 

// create the correct prototype delegation here 
Jill.prototype = Object.create(Person.prototype); 

// the above code, sets Jill's constructor, to Person so we need to set 
// it back to Jill here: 

Jill.prototype.constructor = Jill; 

// add functions on Jill's prototype, these will only be on the Jill object not Person 

Jill.prototype.expressJoy = function() { 
    console.log("Huray!"); 
    }; 

// make a 'Jill' 

var obj = new Jill(); 
console.log(obj instanceof Jill); // true 
obj.expressJoy(); // "Huray!" 
obj.sayName(); // "My name is jill" 

は今、もっと重要なのは、あなたがインスタンス化パターンの2種類を混合され、原型とpseudoclassical、Personは後者、Jillは前者です。

はライアン・アトキンソンにより、以下のブログ投稿からこの素晴らしい絵を見てみましょう:

Blog Post

instantiation Patterns

+0

これらのコメントはあまり意味がありません – Bergi

+0

本当の、固定のおかげで@ベルギー! – JordanHendrix

+0

すごくおかげさまで、ありがとうございました。オブジェクトを単純化することは理にかなっています。私が使用していた例のように、コードをモジュールローダに配置するために作業していたときにIIFE内に配置しました。 – scader

0

をこれはあなたの場合のようなvar Jill行為を

function Person() { 
    this.name = "unnamed"; 
}; 
Person.prototype.sayName = function() { 
    console.log("My name is " + this.name); 
}; 

function Jill() { 
    Jill.prototype.__proto__ = Person.prototype; 

    this.name = "Jill"; 

    Jill.prototype.expressJoy = function() { 
     console.log("Huray!"); 
    }; 

    return Jill; 
}; 

var jill = new Jill(); 
console.log(jill instanceof Jill); // True 
jill.expressJoy(); // Hurray ! 
jill.sayName(); // My name is Jill 
+0

'__proto__'は推奨されていません。それを使用しないでください。 – Bergi

関連する問題