125

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
}
4

4 に答える 4

114

あなたの質問では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

あなたの2番目の例

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何らかの形で役立つことを願っています。

于 2012-10-24T00:47:46.040 に答える
39

どちらの例も同じことをしているようです。

それはあなたの場合に当てはまります。

どちらか一方を選択するのはいつですか。

SomeBaseClass関数本体がある場合、これはnewキーワードで実行されます。通常、これは意図したものではありません。プロトタイプ チェーンをセットアップするだけです。場合によっては、オブジェクトを実際にインスタンス化MyClassするため、深刻な問題を引き起こす可能性さえあります。オブジェクトのプライベート スコープの変数は、同じ特権メソッドを継承するため、すべてのインスタンスで共有されます。他の副作用は想像できる。

したがって、一般的には を好むはずObject.createです。ただし、一部のレガシー ブラウザではサポートされていません。これが、new(明らかな)害を及ぼさないことが多いため、アプローチが頻繁に行われる理由です。この回答もご覧ください。

于 2012-10-23T23:29:38.190 に答える
8

Object.create()意図したとおりに使用すると、違いは明らかです。実際には、コードから単語を完全に隠しprototypeます。フードの下で仕事をします。を使用して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()たとえば、すぐに使用できる「コンストラクター関数」はありません。もちろん、これらのオブジェクト内で自己定義のコンストラクター関数を作成して呼び出すこともできます。

使用するための 1 つの引数は、Javascripts のデフォルトの方法を使用するよりも、他のオブジェクトから /*inherit*を混在させる方が自然Object.create()に見えるかもしれないということです。

于 2012-10-23T23:12:06.030 に答える
0

私は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 を使用して子関数を作成すると、必要のないすべての親プロパティを持つ新しいオブジェクトが返されます。親関数が実行されたくない「New」を使用するオブジェクトまたは関数。

ここに持ち帰りがあります

親関数のいくつかのメソッドに委任したいだけで、新しいオブジェクトを作成したくない場合は、Object.create を使用するのが最善の方法です。

于 2016-01-13T22:26:03.577 に答える