JavaScriptでは、これら2つの例の違いは何ですか:
前提条件:
function SomeBaseClass(){
}
SomeBaseClass.prototype = {
doThis : function(){
},
doThat : function(){
}
}
Object.createを使用した継承の例A:
function MyClass(){
}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
新しいキーワードを使用した継承例B
function MyClass(){
}
MyClass.prototype = new SomeBaseClass();
どちらの例も同じことをしているようです。どちらを選択するのですか?
追加の質問:以下のリンク(15行目)のコードを検討してください。関数の独自のコンストラクターへの参照がプロトタイプに格納されています。なぜこれが便利なのですか?
https://github.com/mrdoob/three.js/blob/master/src/loaders/ImageLoader.js
抜粋(リンクを開きたくない場合):
THREE.ImageLoader.prototype = {
constructor: THREE.ImageLoader
}
あなたの質問であなたはBoth examples seem to do the same thing
と言った、それは全く真実ではない、なぜなら
function SomeBaseClass(){...}
SomeBaseClass.prototype = {
doThis : function(){...},
doThat : function(){...}
}
function MyClass(){...}
MyClass.prototype = Object.create(SomeBaseClass.prototype);
この例では、SomeBaseClass' prototype
を継承していますが、SomeBaseClass
にプロパティがある場合はどうなりますか
function SomeBaseClass(){
this.publicProperty='SomeValue';
}
そして、あなたがそれを
var obj=new MyClass();
console.log(obj.publicProperty); // undefined
console.log(obj);
obj
オブジェクトには、 この例では のようなpublicProperty
プロパティはありません。
MyClass.prototype = new SomeBaseClass();
constructor
関数を実行して、SomeBaseClass
のインスタンスを作成し、SomeBaseClass
オブジェクト全体を継承しています。したがって、使用する場合
var obj=new MyClass();
console.log(obj.publicProperty); // SomeValue
console.log(obj);
この場合、そのpublicProperty
プロパティは、 この例では のようなobj
オブジェクトでも使用できます。
Object.create
は一部の古いブラウザでは使用できないため、その場合は次を使用できます。
if(!Object.create)
{
Object.create=function(o){
function F(){}
F.prototype=o;
return new F();
}
}
上記のコードは、使用できない場合はObject.create
関数を追加するだけなので、Object.create
関数を使用できます。上記のコードはObject.create
が実際に行うことを説明していると思います。それが何らかの形で役立つことを願っています。
どちらの例も同じことをしているようです。
それはあなたの場合に当てはまります。
どちらを選択するのですか?
SomeBaseClass
に関数本体がある場合、これはnew
キーワードで実行されます。これは通常、意図されていません-プロトタイプチェーンをセットアップするだけです。場合によっては、プライベートスコープの変数がすべてのMyClass
インスタンスで共有されているオブジェクトを実際にinstantiateするため、深刻な問題を引き起こす可能性さえあります。同じ特権メソッドを継承するため。他の副作用が考えられます。
したがって、通常はObject.create
。ただし、一部のレガシーブラウザではサポートされていません。これは、new
-アプローチが頻繁に(明らかな)害を与えないため、あまりにも頻繁に表示される理由です。 この答え もご覧ください。
Object.create()
を意図したとおりに使用すると、違いが明らかになります。実際、それはあなたのコードからprototype
Wordを完全に隠します、それは内部で仕事をします。 Object.create()
を使用すると、次のようになります。
_var base = {
doThis : function(){
},
doThat : function(){
}
};
_
そして、これから他のオブジェクトを拡張/継承できます
_var myObject = Object.create( base );
// myObject will now link to "base" via the prototype chain internally
_
したがって、これは別の概念であり、より「オブジェクト指向」の継承方法です。たとえばObject.create()
を使用してすぐに使用できる「コンストラクター関数」はありません。しかしもちろん、これらのオブジェクト内で自己定義constructor functionを作成して呼び出すこともできます。
Object.create()
を使用する1つの引数は、Javascriptを使用するよりもnaturalからmix/* inherit *に見える場合があることですデフォルトway。
私はJavaスクリプトの専門家ではありませんが、ここでは "Object.create"と "new"の違いを理解する簡単な例を示します。
ステップ1:いくつかのプロパティとアクションで親関数を作成します。
function Person() {
this.name = 'venkat';
this.address = 'dallas';
this.mobile='xxxxxxxxxx'
}
Person.prototype.func1 = function () {
return this.name + this.address;
}
ステップ2:Newキーワードを使用して、Person関数の上に拡張する子関数(PersonSalary)を作成します。
function PersonSalary() {
Person.call(this);
}
PersonSalary.prototype = new Person();
PersonSalary();
ステップ3:Object.createキーワードを使用して、Person関数の上に拡張する2番目の子関数(PersonLeaves)を作成します。
function PersonLeaves() {
Person.call(this);
}
PersonLeaves.prototype = Object.create(Person.prototype);
PersonLeaves();
//次に、両方の子関数のプロトタイプを確認します。
PersonSalary.prototype
PersonLeaves.prototype
これらの子関数は両方ともPerson(parent function)プロトタイプにリンクし、そのメソッドにアクセスできますが、newを使用して子関数を作成すると、必要のないすべての親プロパティを含む真新しいオブジェクトを返します。親関数が実行されたくない「新規」を使用するオブジェクトまたは関数。
ここにテイクアウトがあります
親関数のいくつかのメソッドに委任したいだけで、新しいオブジェクトを作成したくない場合は、Object.createを使用するのが最善の方法です。