8

オブジェクト指向 Javascript のいくつかの側面を学んでいます。私はこのスニペットに出くわしました

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

Object.defineProperties(Person.prototype, {
  sayHi: {
    value: function() {
      return "Hi my name is " + this.firstName;
    }
  },
  fullName: {
    get: function() {
      return this.firstName + " " + this.lastName;
    }
  }
});

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

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

var john = new Employee("John", "Doe", "Dev");

そして私の質問は: なぜこのスニペットは Object.create(Person.prototype) を使用するのですか? プロトタイプを次のように単純にリセットするべきではありません:

Employee.prototype = Person.prototype;
4

2 に答える 2

9

Employee.prototype = Person.prototype を実行することは、「従業員は人です」ではなく、「従業員は人です」と言っているようなものです。いずれかのプロトタイプへの変更は、両方のクラスに反映されます。

これがデモンストレーションです。当然のことながら、Persons には役職がないため、Persons を働かせたくありません。

したがって、Object.create を使用せずにプロトタイプ チェーンをセットアップする正しい方法は次のとおりです。

Employee.prototype = new Person;

ただし、これにはオブジェクトのインスタンス化が必要であり、これは少しファンキーです。特に、Person のコンストラクターを呼び出したくない場合はそうです。必要かどうかに関係なく、すべての Employee インスタンスは未定義の「firstName」および「lastName」プロパティを継承します。

この場合、大したことではありません。Employee コンストラクターは、Person から継承されたプロパティに取って代わるプロパティを自身に設定します。しかし、この例を考えてみてください。freeTime は、プロトタイプにないためコピーされない Person のインスタンス レベルのプロパティであると考える人もいるかもしれません。さらに、Employee から Person コンストラクターを呼び出したことはありません。そうではありません --オブジェクトをインスタンス化する必要があったため、freeTimeがEmployee プロトタイプに設定されました。

したがって、できる最善かつ最もクリーンな継承は、Object.create を使用することです。親クラスのコンストラクターを呼び出したい場合は、サブクラスのコンストラクター内から明示的に呼び出すことができます。もう 1 つの良い点は、Object.create には defineProperties に対する 2 番目の (オプションの) 引数があることです。したがって、これを行うこともできます:

Employee.prototype = Object.create(Person.prototype, {
  work: {
    value: function() {
      return this.fullName+" is doing some "+this.position+" stuff");  
    }
  }
});

もちろん、レガシー ブラウザーをサポートする必要がある場合は、Object.create を使用できません。代替手段は、アンダースコアやロダッシュなどのライブラリからクローン/拡張を使用することです。または、この小さなダンスがあります。

var subclass = function() { };
subclass.prototype = Person.prototype;
Employee.prototype = new subclass;
于 2013-02-23T21:00:11.923 に答える
1

私の推測では、Person からの単なる参照ではなく、新しいオブジェクトを作成することが意図されています。

//create a new object with its prototype assigned to Person.prototype
Employee.prototype = Object.create(Person.prototype);
于 2013-02-23T20:19:52.917 に答える