なぜプロトタイプコンストラクタを設定する必要があるのですか?


294

ではMDN記事の継承に関するセクションJavascriptのオブジェクト指向入門、私は彼らがprototype.constructorを設定気づきました:

// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;  

これは重要な目的に役立ちますか?省略しても大丈夫ですか?


23
あなたがこれを聞いてくれてうれしい:私は昨日同じドキュメントを読み、コンストラクタも明示的に設定する背後にある理由にも興味を持ちました。
ワイリー

6
私はこれを指摘しなければならなかった、この質問はあなたがリンクした記事にリンクされています!
マリー

7
何も必要ありません
nothingisnecessary

1
subclass.prototype.constructor指すようになりparent_class、あなたが書いていない場合はsubclass.prototype.constructor = subclass、つまり、subclass.prototype.constructor()直接使用すると予期しない結果が生じます。
KuanYu Chu

回答:


263

常に必要なわけではありませんが、用途はあります。基本Personクラスでコピーメソッドを作成したいとします。このような:

// define the Person Class  
function Person(name) {
    this.name = name;
}  

Person.prototype.copy = function() {  
    // return new Person(this.name); // just as bad
    return new this.constructor(this.name);
};  

// define the Student class  
function Student(name) {  
    Person.call(this, name);
}  

// inherit Person  
Student.prototype = Object.create(Person.prototype);

新しいものを作成してStudentコピーするとどうなりますか?

var student1 = new Student("trinth");  
console.log(student1.copy() instanceof Student); // => false

コピーはのインスタンスではありませんStudent。これは(明示的なチェックがない場合)、Student「ベース」クラスからコピーを返す方法がないためです。返されるのはのみPersonです。ただし、コンストラクタをリセットした場合:

// correct the constructor pointer because it points to Person  
Student.prototype.constructor = Student;

...その後、すべてが期待どおりに機能します:

var student1 = new Student("trinth");  
console.log(student1.copy() instanceof Student); // => true

34
注:constructorJSでは属性は特別な意味を持たないため、呼び出すこともできますbananashake。唯一の違いは、関数を宣言するたびにエンジンが自動的に初期化constructorf.prototypeれることですf。ただし、いつでも上書きできます。
user123444555621

58
@ Pumbaa80-私はあなたの要点を理解しますが、エンジンが自動的に初期化constructorするという事実は、それ JSで特別な意味を持つことを意味します。
ウェイン

13
あなたが言った動作が機能する理由は、のreturn new this.constructor(this.name);代わりにを使用しているためであることを明確にしたいだけですreturn new Person(this.name);this.constructorStudent関数なので(で設定したためStudent.prototype.constructor = Student;)、copy関数は最終的にStudent関数を呼び出します。//just as badコメントであなたの意図が何だったかはわかりません。
CEGRD

12
@lwburk「//と同じくらい悪い」とはどういう意味ですか?
CEGRD

6
理解できたと思います。しかし、Studentコンストラクタが次のような追加の引数を追加した場合はどうなりStudent(name, id)ますか?次に、copy関数をオーバーライドして、そのPerson内部からバージョンを呼び出し、さらに追加のidプロパティをコピーする必要がありますか?
snapfractalpop 2014年

76

これは重要な目的に役立ちますか?

はいといいえ。

ES5以前では、JavaScript自体はconstructor何にも使用しませんでした。これは、関数の上のデフォルトオブジェクトと定義prototypeプロパティはそれを持って、それが関数に戻って参照することを考えて、それはそれでした。仕様ではそれ以外のことは何も言及していません。

これは、継承階層に関連して使用を開始したES2015(ES6)で変更されました。たとえば、返すプロミスを作成するときに、(SpeciesConstructorを介して)呼び出したプロミスPromise#thenconstructorプロパティを使用します。また、ArraySpeciesCreateを介して配列のサブタイプを作成することにも関与しています。)。

言語自体の外では、一般的な「クローン」関数を作成しようとするとき、または一般に、オブジェクトのコンストラクター関数であると信じるものを参照したいときに、それを使用することがあります。私の経験ではそれを使用することはまれですが、時々人々はそれを使用します。

省略しても大丈夫ですか?

それはデフォルトでそこにあります、あなたが関数のプロパティのオブジェクトを置き換えるとき、それを戻す必要があるだけですprototype

Student.prototype = Object.create(Person.prototype);

これを行わない場合:

Student.prototype.constructor = Student;

...その後、(おそらく)をStudent.prototype.constructor継承しPerson.prototypeますconstructor = Person。したがって、誤解を招く可能性があります。そしてもちろん、それを使用するもの(PromiseまたはArray)をサブクラス化し、class¹(これを処理する)を使用しない場合は、正しく設定する必要があります。だから基本的に:それは良い考えです。

コード(または使用するライブラリコード)で何も使用していなくても問題ありません。私は常にそれが正しく配線されていることを確認しました。

もちろん、ES2015(別名ES6)のclassキーワードを使用すると、ほとんどの場合それを使用していましたが、使用するときに処理されるため、これ以上使用する必要はありません。

class Student extends Person {
}

¹ 「...を使用するもの(PromiseまたはArray)をサブクラス化していてclass... を使用しない場合」  — 可能ですが、それは本当に苦痛(そして少し愚かなこと)です。あなたが使用する必要がありますReflect.construct


12

TLDR; それほど必要ではありませんが、おそらく長期的には役立つでしょう。そうする方がより正確です。

注:私の以前の回答が混乱して書かれていて、急いで回答しなかったいくつかのエラーがあったため、多くの編集が行われました。いくつかの重大なエラーを指摘した人々に感謝します。

基本的には、Javascriptでサブクラス化を正しく配線することです。サブクラスを作成するときは、prototypeオブジェクトの上書きなど、プロトタイプの委任が正しく機能することを確認するために、いくつかファンキーなことを行う必要があります。prototypeオブジェクトの上書きには、constructorため、参照を修正する必要があります。

ES5の「クラス」の仕組みを簡単に見ていきましょう。

コンストラクタ関数とそのプロトタイプがあるとしましょう:

//Constructor Function
var Person = function(name, age) {
  this.name = name;
  this.age = age;
}

//Prototype Object - shared between all instances of Person
Person.prototype = {
  species: 'human',
}

インスタンス化するコンストラクタを呼び出すときは、次のように言いますAdam

// instantiate using the 'new' keyword
var adam = new Person('Adam', 19);

new「人」で呼び出されたキーワードは、基本的には、コードのいくつかの追加のラインを持つ人のコンストラクタを実行します:

function Person (name, age) {
  // This additional line is automatically added by the keyword 'new'
  // it sets up the relationship between the instance and the prototype object
  // So that the instance will delegate to the Prototype object
  this = Object.create(Person.prototype);

  this.name = name;
  this.age = age;

  return this;
}

/* So 'adam' will be an object that looks like this:
 * {
 *   name: 'Adam',
 *   age: 19
 * }
 */

私たちのconsole.log(adam.species)場合、ルックアップはadamインスタンスで失敗し、プロトタイプチェーンをその.prototypeまでルックアップします。つまり、プロパティPerson.prototypePerson.prototype 持っている.speciesため、ルックアップはで成功しPerson.prototypeます。次にログに記録します'human'

ここでは、Person.prototype.constructorは正しくを指しPersonます。

ここで興味深いのは、いわゆる「サブクラス化」です。Studentクラスを作成する場合、それはクラスのサブクラスでありPerson、いくつかの追加の変更が加えられているため、次のことを確認する必要があります。Student.prototype.constructor、正確を期すためにStudentを指すます。

それ自体ではこれを行いません。サブクラス化すると、コードは次のようになります。

var Student = function(name, age, school) {
 // Calls the 'super' class, as every student is an instance of a Person
 Person.call(this, name, age);
 // This is what makes the Student instances different
 this.school = school
}

var eve = new Student('Eve', 20, 'UCSF');

console.log(Student.prototype); // this will be an empty object: {}

new Student()ここで呼び出すと、必要なすべてのプロパティを持つオブジェクトが返されます。ここで、をチェックするとeve instanceof Person、が返されfalseます。にアクセスしようとするとeve.species、戻りますundefinedます。

つまり、eve instanceof Persontrue を返し、Studentデリゲートのインスタンスがに正しく渡されるようにStudent.prototype、デリゲートを結び付ける必要がありPerson.prototypeます。

しかし、それをnewキーワードで呼び出しているので、その呼び出しが何を追加するか覚えていますか?それは呼ぶだろうObject.create(Student.prototype)、我々は間のdelegational関係を設定する方法である、StudentStudent.prototype。現在、Student.prototype空であることに注意してください。したがって、にのみ委任されているため.species、のインスタンスのStudent検索は失敗し、プロパティはに存在しません。 Student.prototype.speciesStudent.prototypeます。

に代入Student.prototypeするとObject.create(Person.prototype)Student.prototypeそれ自体がに委譲されPerson.prototype、期待どおりにルックアップeve.speciesが戻りhumanます。おそらく、Student.prototype AND Person.prototypeから継承する必要があります。したがって、すべてを修正する必要があります。

/* This sets up the prototypal delegation correctly 
 *so that if a lookup fails on Student.prototype, it would delegate to Person's .prototype
 *This also allows us to add more things to Student.prototype 
 *that Person.prototype may not have
 *So now a failed lookup on an instance of Student 
 *will first look at Student.prototype, 
 *and failing that, go to Person.prototype (and failing /that/, where do we think it'll go?)
*/
Student.prototype = Object.create(Person.prototype);

これで委任は機能しますが、ので上書きStudent.prototypeしていますPerson.prototype。したがって、を呼び出すとStudent.prototype.constructorPersonではなくを指しStudentます。これが、修正する必要がある理由です。

// Now we fix what the .constructor property is pointing to    
Student.prototype.constructor = Student

// If we check instanceof here
console.log(eve instanceof Person) // true

ES5では、constructorプロパティは、「コンストラクター」になることを意図して記述した関数を参照する参照です。何を除いてnewキーワードが私たちを与える、コンストラクタは、そうでない場合は「プレーン」関数です。

ES6では、constructorクラスの記述方法にが組み込まれました。これは、クラスを宣言するときのメソッドとして提供されます。これは単に構文上の砂糖ですがsuper、既存のクラスを拡張するときのaへのアクセスなど、いくつかの便利さを備えています。したがって、上記のコードを次のように記述します。

class Person {
  // constructor function here
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  // static getter instead of a static property
  static get species() {
    return 'human';
  }
}

class Student extends Person {
   constructor(name, age, school) {
      // calling the superclass constructor
      super(name, age);
      this.school = school;
   }
}

eve instanceof Student戻りましたtrue。説明については、stackoverflow.com / questions / 35537995 /…を参照してください。また、which is, at the moment, nothing何を言っているのですか?すべての関数はプロトタイプを持っているので、私がチェックするStudent.prototypeとそれは何かです。
Aseem Bansal 2016

私の間違い。falseを返す「eve instanceof Person」を読み取る必要があります。その部分を修正します。すべての関数にプロトタイププロパティがあることは正しいです。ただし、プロトタイプをObject.create(Person.prototype)に割り当てないと、Student.prototypeは空になります。したがって、ログに記録eve.speciesすると、スーパークラスのPersonまで適切に委任されず、ログに記録されません'human'。おそらく、すべてのサブクラスがそのプロトタイプとそのスーパーのプロトタイプから継承することを望んでいます。
bthehuman 2016

明確にするためにwhich is, at the moment, nothing、私はStudent.prototypeオブジェクトが空であることを意味しました。
bthehuman 2016

プロトタイプの詳細:Student.prototypeto の割り当てなしObject.create(Person.prototype)-つまり、思い出すと、Personのすべてのインスタンスがdelegateに設定されているのと同じ方法Person.prototype-のインスタンスのプロパティStudentを検索すると、にのみ delegateしStudent.prototypeます。したがってeve.species、そのルックアップは失敗します。これを割り当てると、Student.prototypeそれ自体がに委任されPerson.prototype、ルックアップeve.speciesはに戻りhumanます。
bthehuman 2016

「サブクラス化」をエミュレートしようとするときに必要なことがinstanceいくつかあります:「インスタンスが「サブクラス」コンストラクタであるかどうかをチェックするときに、それは正確になります。」いいえ、instanceof使用しませんconstructor「しかし、生徒の.prototype.constructorを検索しても、それでもPersonをポイントします」いいえ、そうStudentです。この例の意味がわかりません。コンストラクターで関数を呼び出すことは継承ではありません。「ES6では、コンストラクタは、実際の関数の代わりに、関数への参照、今ある」ええと、何が?
Felix Kling 2016

10

同意しません。プロトタイプを設定する必要はありません。まったく同じコードを使用しますが、prototype.constructor行を削除します。何か変化はありますか?いいえ。次の変更を行います。

Person = function () {
    this.favoriteColor = 'black';
}

Student = function () {
    Person.call(this);
    this.favoriteColor = 'blue';
}

そしてテストコードの最後に...

alert(student1.favoriteColor);

色はブルーになります。

私の経験では、prototype.constructorへの変更は、おそらくとにかく良いプラクティスではない非常に具体的で非常に複雑なことを行わない限り、あまり効果がありません:)

編集:少しWebを調べて実験を行ったところ、「new」で構築されているものに「見える」ようにコンストラクターが設定されているようです。これに関する問題は、javascriptがプロトタイプ言語であることだと私は主張するでしょう-継承などのものはありません。しかし、ほとんどのプログラマーは、継承を「道」として押し進めるプログラミングのバックグラウンドを持っています。したがって、この原型言語を「クラシック」言語にするために、あらゆる種類のことを考え出します。たとえば、「クラス」の拡張などです。実際、彼らが与えた例では、新しい学生は人です-それは別の学生から「伸びている」というわけではありません。学生はすべて人に関するものであり、人が何であれ学生でもあります。学生を拡張し、あなたが何であれ

Crockfordは少しクレイジーで熱狂的ですが、彼が書いたもののいくつかについて真剣に読んでください。


8
これはプロトタイプチェーンを継承しません。
Cypher、

1
@Cypherのスロークラップは、4年後の会話へようこそ。そうです、prototype.constructor を上書きするかどうかに関係なく、prototypeチェーン継承されます。テストしてみてください。
Stephen

7
プロトタイプを継承するコードがありません。インターネットへようこそ。
Cypher

1
@Cypherコードスニペットは、リンクされた記事のコードに基づいていました。質問全体を読むことへようこそ。ああ。待つ。
Stephen

1
@macher私はそれを古典的な継承として意味しました。私の言い回しの選択が悪い。
Stephen

9

これには大きな落とし穴があります。

Student.prototype.constructor = Student;

しかし、プロトタイプもPersonであるTeacherがいて、あなたが書いた場合

Teacher.prototype.constructor = Teacher;

その後、生徒のコンストラクタは教師になります。

編集:Mozillaの例のように、Object.createを使用して作成されたPersonクラスの新しいインスタンスを使用してStudentおよびTeacherプロトタイプを設定したことを確認することで、これを回避できます。

Student.prototype = Object.create(Person.prototype);
Teacher.prototype = Object.create(Person.prototype);

1
Student.prototype = Object.create(...)この質問では想定されています。この答えは、混乱を招くだけです。
アンドレ・Chalella

3
@AndréNevesこの回答は役に立ちました。Object.create(...)質問を生み出したMDN記事で使用されていますが、質問自体では使用されていません。クリックしない人は多いと思います。
Alex Ross

質問で参照されているリンクされた記事はすでにObject.create()を使用しています。この回答と編集の編集はあまり関係がなく、控えめに言っても混乱します:-)
Drenai

1
広義の点は、Javascriptプロトタイプの初心者を悩ませる落とし穴があるということです。2016年に議論する場合は、ES6クラス、Babel、Typescriptを実際に使用する必要があります。しかし、この方法でクラスを手動で構築したい場合は、プロトタイプチェーンが実際にどのように機能してその能力を活用するかを理解するのに役立ちます。プロトタイプとして任意のオブジェクトを使用できますが、別のオブジェクトを新しくしたくない場合もあります。さらに、HTML 5が完全に普及する前は、Object.createが常に利用できるとは限らなかったため、クラスを誤って設定する方が簡単でした。
James D

5

これまでのところ混乱はまだあります。

次のように既存のオブジェクトがあるので、元の例に従いますstudent1

var student1 = new Student("Janet", "Applied Physics");

どのようstudent1に作成されるのか知りたくない場合は、そのような別のオブジェクトが必要なだけで、次のstudent1ようなコンストラクタープロパティを使用できます。

var student2 = new student1.constructor("Mark", "Object-Oriented JavaScript");

ここではStudent、コンストラクタプロパティが設定されていない場合、プロパティの取得に失敗します。むしろ、Personオブジェクトを作成します。


2

プロトタイプコンストラクターを設定することが本当に必要な理由のコード例を手に入れました。

function CarFactory(name){ 
   this.name=name;  
} 
CarFactory.prototype.CreateNewCar = function(){ 
    return new this.constructor("New Car "+ this.name); 
} 
CarFactory.prototype.toString=function(){ 
    return 'Car Factory ' + this.name;
} 

AudiFactory.prototype = new CarFactory();      // Here's where the inheritance occurs 
AudiFactory.prototype.constructor=AudiFactory;       // Otherwise instances of Audi would have a constructor of Car 

function AudiFactory(name){ 
    this.name=name;
} 

AudiFactory.prototype.toString=function(){ 
    return 'Audi Factory ' + this.name;
} 

var myAudiFactory = new AudiFactory('');
  alert('Hay your new ' + myAudiFactory + ' is ready.. Start Producing new audi cars !!! ');            

var newCar =  myAudiFactory.CreateNewCar(); // calls a method inherited from CarFactory 
alert(newCar); 

/*
Without resetting prototype constructor back to instance, new cars will not come from New Audi factory, Instead it will come from car factory ( base class )..   Dont we want our new car from Audi factory ???? 
*/

あなたのcreateNewCar方法は工場を作っています!?また、これはvar audiFactory = new CarFactory("Audi")継承を使用するのではなく、本来使用されるべきだったようです。
ベルギ

あなたの例はthis.constructor内部で使用しているので、設定する必要があるのは当然のことです。それなしの例はありますか?
Dmitri Zaitsev

1

最近では、関数型の「クラス」や「新規」を使用する必要はありません。オブジェクトリテラルを使用します。

Objectプロトタイプはすでに「クラス」です。オブジェクトリテラルを定義すると、それはすでにプロトタイプオブジェクトのインスタンスです。これらは、別のオブジェクトのプロトタイプなどとしても機能します。

const Person = {
  name: '[Person.name]',
  greeting: function() {
    console.log( `My name is ${ this.name || '[Name not assigned]' }` );
  }
};
// Person.greeting = function() {...} // or define outside the obj if you must

// Object.create version
const john = Object.create( Person );
john.name = 'John';
console.log( john.name ); // John
john.greeting(); // My name is John 
// Define new greeting method
john.greeting = function() {
    console.log( `Hi, my name is ${ this.name }` )
};
john.greeting(); // Hi, my name is John

// Object.assign version
const jane = Object.assign( Person, { name: 'Jane' } );
console.log( jane.name ); // Jane
// Original greeting
jane.greeting(); // My name is Jane 

// Original Person obj is unaffected
console.log( Person.name ); // [Person.name]
console.log( Person.greeting() ); // My name is [Person.name]

これは読む価値があります

JavaやC ++などのクラスベースのオブジェクト指向言語は、クラスとインスタンスという2つの異なるエンティティの概念に基づいています。

...

JavaScriptなどのプロトタイプベースの言語では、この区別はありません。単にオブジェクトがあるだけです。プロトタイプベースの言語には、プロトタイプオブジェクトという概念があります。これは、新しいオブジェクトの初期プロパティを取得するためのテンプレートとして使用されるオブジェクトです。オブジェクトは、作成時または実行時に、独自のプロパティを指定できます。さらに、任意のオブジェクトを別のオブジェクトのプロトタイプとして関連付けることができるため、2番目のオブジェクトが最初のオブジェクトのプロパティを共有できます。


1

toStringモンキーパッチなしの代替手段が必要な場合に必要です。

//Local
foo = [];
foo.toUpperCase = String(foo).toUpperCase;
foo.push("a");
foo.toUpperCase();

//Global
foo = [];
window.toUpperCase = function (obj) {return String(obj).toUpperCase();}
foo.push("a");
toUpperCase(foo);

//Prototype
foo = [];
Array.prototype.toUpperCase = String.prototype.toUpperCase;
foo.push("a");
foo.toUpperCase();

//toString alternative via Prototype constructor
foo = [];
Array.prototype.constructor = String.prototype.toUpperCase;
foo.push("a,b");
foo.constructor();

//toString override
var foo = [];
foo.push("a");
var bar = String(foo);
foo.toString = function() { return bar.toUpperCase(); }
foo.toString();

//Object prototype as a function
Math.prototype = function(char){return Math.prototype[char]};
Math.prototype.constructor = function() 
  {
  var i = 0, unicode = {}, zero_padding = "0000", max = 9999;
  
  while (i < max) 
    {
    Math.prototype[String.fromCharCode(parseInt(i, 16))] = ("u" + zero_padding + i).substr(-4);

    i = i + 1;
    }    
  }

Math.prototype.constructor();
console.log(Math.prototype("a") );
console.log(Math.prototype["a"] );
console.log(Math.prototype("a") === Math.prototype["a"]);


これは何をすることになっていますか?foo.constructor()??
Ry-

0

編集、私は実際には間違っていました。行をコメントアウトしても、動作はまったく変わりません。(私はそれをテストしました)


はい、必要です。あなたがするとき

Student.prototype = new Person();  

Student.prototype.constructorになりPersonます。したがって、呼び出しStudent()はによって作成されたオブジェクトを返しますPerson。あなたがするなら

Student.prototype.constructor = Student; 

Student.prototype.constructorにリセットされStudentます。これで、Student()それを実行しStudent、親コンストラクターを呼び出すとParent()、正しく継承されたオブジェクトが返されます。Student.prototype.constructor呼び出す前にリセットしなかった場合は、プロパティが設定されていないオブジェクトを取得しますStudent()


3
プロトタイプ構成は人物になる可能性がありますが、人物からすべてのプロパティとメソッドを継承しているため、これは適切です。prototype.constructorを設定せずに新しいStudent()を作成すると、独自のコンストラクタが適切に呼び出されます。
Stephen

0

与えられた単純なコンストラクタ関数:

function Person(){
    this.name = 'test';
}


console.log(Person.prototype.constructor) // function Person(){...}

Person.prototype = { //constructor in this case is Object
    sayName: function(){
        return this.name;
    }
}

var person = new Person();
console.log(person instanceof Person); //true
console.log(person.sayName()); //test
console.log(Person.prototype.constructor) // function Object(){...}

デフォルトでは(仕様https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor)、すべてのプロトタイプは、上の関数を指すコンストラクターと呼ばれるプロパティを自動的に取得しますプロパティです。コンストラクターによっては、他のプロパティとメソッドがプロトタイプに追加される場合がありますが、これはあまり一般的な方法ではありませんが、拡張には許可されています。

したがって、単純に答えます。prototype.constructorの値が、仕様で想定されているとおりに正しく設定されていることを確認する必要があります。

この値を常に正しく設定する必要がありますか?デバッグに役立ち、内部構造を仕様と一致させます。APIがサードパーティによっていつ使用されているかは間違いなくありますが、実際にコードがランタイムで実行されるときはそうではありません。


0

MDNの例を1つ示します。MDNの使用方法を理解するのに非常に役立ちました。

JavaScriptでは、AsyncFunctionオブジェクトasync functionsを返すものが用意されています。AsyncFunctionグローバルオブジェクトではありませんが、constructorプロパティを使用して取得し、利用することができます。

function resolveAfter2Seconds(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

// AsyncFunction constructor
var AsyncFunction = Object.getPrototypeOf(async function(){}).constructor

var a = new AsyncFunction('a', 
                          'b', 
                          'return await resolveAfter2Seconds(a) + await resolveAfter2Seconds(b);');

a(10, 20).then(v => {
  console.log(v); // prints 30 after 4 seconds
});

-1

それは必要ない。これは、伝統的なOOPチャンピオンがJavaScriptのプロトタイプの継承をクラシックの継承に変えようとする多くのことの1つにすぎません。次のことだけ

Student.prototype.constructor = Student; 

そう、現在の「コンストラクタ」の参照を持っているということです。

正しいとマークされているウェインの答えでは、次のコードとまったく同じことができます

Person.prototype.copy = function() {  
    // return new Person(this.name); // just as bad
    return new this.constructor(this.name);
};  

以下のコードで(this.constructorをPersonに置き換えてください)

Person.prototype.copy = function() {  
    // return new Person(this.name); // just as bad
    return new Person(this.name);
}; 

ES6を使用すると、古典的な継承の純粋主義者は、class、extends、superなどの言語のネイティブ演算子を使用でき、プロトタイプやコンストラクタの修正や親の参照などを確認する必要がないことを感謝します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.