JavaScript対象に向かう継承原理と実現方法の分析


本論文の実例は、JavaScriptが対象に向けて継承原理と実施方法を説明する。皆さんに参考にしてあげます。具体的には以下の通りです。
1、構造関数、原型と実例の関係
構造関数はプロトタイプ属性prototypeがプロトタイプオブジェクトを指しています。
プロトタイプオブジェクトは、構造関数を指すポインタconstructor を含む。
例は、プロトタイプオブジェクトを指す内部ポインタ[[prototype]] を含む。
2、プロトタイプチェーンによる継承
基本思想:原型を利用して、一つの引用タイプに別の参照タイプの属性と方法を継承させ、サブタイプは超タイプのすべての属性と方法にアクセスすることができます。プロトタイプチェーンの構築は,他のコンストラクタのプロトタイプに対して1つのタイプのインスタンスを与えて実現した。実現の本質は元のオブジェクトを書き換えることであり、新しいタイプの実例を代用することである。

function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function() {
  alert("Hello, " + this.name);
}
var person = new Person("Alice");
person.sayHello(); // Hello, Alice
function Student() {
}
Student.prototype = new Person("Bruce");
Student.prototype.id = 16;
Student.prototype.showId = function() {
  alert(this.id);
}
var student = new Student();
student.sayHello(); // Hello, Bruce
student.showId(); // 16

注意:対象の字面量でプロトタイプを作成することはできません。このようにプロトタイプのチェーンを書き換えて、継承が無効になります。

function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function() {
  alert("Hello, " + this.name);
}
var person = new Person("Alice");
person.sayHello(); // Hello, Alice
function Student() {
}
Student.prototype = new Person("Bruce");
Student.prototype.id = 16;
Student.prototype = {
  showId: function() {
    alert(this.id);
  }
};
var student = new Student();
student.sayHello(); //   :student.sayHello is not a function
student.showId(); // 16

StudentはStudentのプロトタイプを指し、StudentのプロトタイプはPersonのプロトタイプを指す。student.sayHello()プロトタイプチェーン検索メカニズム:
1)検索studentの例にsayHello()があるかどうか
2)Student.prototypeを検索するとsayHello()がありますか?
3)Person.prototypeを検索するとsayHello()がありますか?
サブタイプは、スーパータイプのある方法をカバーする必要がある場合があります。または、スーパータイプの中には存在しない方法を追加する必要があります。

function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function() {
  alert("Hello, " + this.name);
}
var person = new Person("Alice");
person.sayHello(); // Hello, Alice
function Student() {
}
Student.prototype = new Person("Bruce");
Student.prototype.id = 16;
Student.prototype.showId = function() {
alert(this.id);
}
Student.prototype.sayHello = function() {
  alert("Hi, " + this.name);
}
var student = new Student();
student.sayHello(); //Hi, Bruce
student.showId(); // 16

注意:原型をカバーしたり、方法を追加したりするコードは、必ず原型を置換した語句の後に置いてください。

function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function() {
  alert("Hello, " + this.name);
}
var person = new Person("Alice");
person.sayHello(); // Hello, Alice
function Student() {
}
Student.prototype.sayHello = function() {
  alert("Hi, " + this.name);
}
Student.prototype = new Person("Bruce");
Student.prototype.id = 16;
Student.prototype.showId = function() {
alert(this.id);
}
var student = new Student();
student.sayHello(); // Hello, Bruce
student.showId(); // 16

インスタンスとプロトタイプの関係を決定します。
(1)instance of

alert(student instanceof Object); // true
alert(student instanceof Student); // true
alert(student instanceof Person); // true

(2)isPrott ptype Of

alert(Object.prototype.isPrototypeOf(student)); // true
alert(Student.prototype.isPrototypeOf(student)); // true
alert(Person.prototype.isPrototypeOf(student)); // true

(3)get ProttotypeOf

Object.getPrototypeOf(student1) == Student.prototype

プロトタイプチェーンを使って継承を実現する問題:
(1)引用タイプの属性は実例によって共有され、原型が継承されると、原型は別のタイプのインスタンスになり、インスタンスの属性は現在のプロトタイプの属性となり、共有される。

function Person(name, age) {
  this.friends = ["Cindy","David"];
}
function Student() {
}
Student.prototype = new Person();
var student1 = new Student();
student1.friends.push("Bruce");
alert(student1.friends); // "Cindy","David","Bruce"
var student2 = new Student();
alert(student1.friends); // "Cindy","David","Bruce"

(2)サブタイプのインスタンスを作成する際に、超タイプの構造関数にパラメータを渡すことはできないが、実際には、すべてのオブジェクトインスタンスに影響を与えない場合には、超タイプの構造関数にパラメータを伝えることはできないはずである。
実際にはプロトタイプチェーンを単独で使うことは少ない。
3、構造関数による継承
基本的な考え:サブタイプのコンストラクタの内部で超タイプのコンストラクタを呼び出します。apply()およびcall()の方法を使用することによって、新たに作成されたオブジェクト上で構造関数を実行することもできる。

function Person(name, age) {
  this.name = name;
  this.age = age;
}
function Student() {
  Person.call(this,"Alice",22); //        Person,        
  this.id = 16; //     
}
var student = new Student();
alert(student.name); // "Alice"
alert(student.age); // 22
alert(student.id); // 16

構造関数を使って継承を実現する問題:
(1)超タイプのプロトタイプで定義された方法は、サブタイプには見えないが、結果として、すべてのタイプはコンストラクターモードしか使用できない。
(2)サブクラスがスーパークラスの定義にアクセスできるようにするには、方法はコンストラクタでしか定義できないが、方法はコンストラクタで定義されている場合、関数多重は語れない。

function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.showName = function() {
  alert(this.name);
};
function Student() {
  Person.call(this,"Alice",22);
  this.id = 16;
}
var student = new Student();
alert(student.showName()); //   :student.showName is not a function

実際には単独でのコンストラクタの使用は少ない。継承を実現するために。
4、原型チェーンと構造関数を組み合わせて継承を実現する
アイデア:原型チェーンを使って共有の属性と方法を継承し、構造関数を使って実例的な属性を継承します。
プロトタイプ上の定義方法によって関数多重が実現されただけでなく、各インスタンスに独自の属性があることが保証されます。

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.friends = ["Cindy","David"];
}
Person.prototype.sayHello = function() {
  alert("Hello, " + this.name);
}
function Student(name, age, id) {
  Person.call(this, name, age);
  this.id = id;
}
Student.prototype = new Person();
Student.prototype.showId = function() {
  alert(this.id);
}
var student1 = new Student("Alice", 22, 16);
student1.friends.push("Emy");
alert(student1.friends); // "Cindy","David","Emy"
student1.sayHello(); // Hello, Alice
student1.showId(); // 16
var student2 = new Student("Bruce", 23, 17);
alert(student2.friends); // "Cindy","David"
student2.sayHello(); // Hello, Bruce
student2.showId(); // 17

もっと多くのJavaScriptに関する内容に興味がある読者は、当駅のテーマを見ることができます。「javascript対象向け入門教程」、「JavaScriptエラーとデバッグテクニックのまとめ」、「JavaScriptデータ構造とアルゴリズム技術のまとめ」、「JavaScriptはアルゴリズムと技術の総括を遍歴します。」および「JavaScript数学演算の使い方のまとめ
本論文で述べたように、JavaScriptプログラムの設計に役に立ちます。