序文
プロトタイプ、プロトタイプチェーン、原型継承するため、各フロントエンドスタッフがオフになるための基礎です。ほとんど常に見て、それは2を超えることができたときに、単に記事について書く、一時間は他の人の記事を何回も見(明確にこれらの問題を理解し、実際に知っている、書く方が良いです、面接のプロトタイプ、これらの質問のプロトタイプチェーンの間に尋ねました日)が忘れられます。
プロトタイプの理解
私たちは、作成された
每个函数都有一个prototype(原型)属性
、このプロパティは一个指针,指向一个对象
、この趣旨及び目的は、特定のタイプのすべてのインスタンスを包含することです共享的属性和方法
。プロトタイプ(試作品)があります通过调用构造函数而创建的那个对象实例的原型对象
。プロトタイプオブジェクトを使用する利点は、それが共有の例が含まれたオブジェクトのすべてのプロパティとメソッドを与えることです。
function Animal(){}
Animal.prototype.name = 'animal';
Animal.prototype.age = '10';
Animal.prototype.sayName = function(){
console.log(this.name);
}
let dog = new Animal();
dog.sayName(); // 输出 animal
let cat = new Animal();
cat.sayName(); // 输出 animal
复制代码
上記のコードを使用プロトタイプ説明プロパティおよびメソッドを共有します。プロパティとメソッドは、動物のコンストラクタ関数が空になるのプロトタイプに追加されます。犬のインスタンス動物()、または猫のインスタンスアニマル()かどうかは、同じ属性セットと同じsayName()関数へのアクセス権を持っています。オブジェクトインスタンスのプロパティを追加する場合、同じ名前の遮蔽性は、プロトタイプオブジェクト属性に格納されます。
function Animal(){}
// 常用原型写法
Animal.prototype = {
name: 'animal',
age: '10',
sayName: function(){
console.log(this.name);
}
};
let dog = new Animal();
dog.sayName(); // 输出 animal
let cat = new Animal();
cat.name = 'Tom';
cat.sayName(); // 输出 Tom
复制代码
私は先に述べた:プロトタイプ(試作品)は、コンストラクタインスタンスを呼び出すことによって作成されたオブジェクトオブジェクトのプロトタイプです。デフォルトでは、すべてが自動的に関数プロトタイププロパティに場所のポインタへのポインタを含むプロトタイプオブジェクトのコンストラクタ(コンストラクタ)プロパティを得ます。下図のように:
動物犬と猫の各インスタンスは、内部属性が含まれています
仅仅指向了Animal.prototype
。つまり、彼らは、コンストラクタに直接関係はありません。
プロトタイプチェーンを理解します
基本的な考え方は、参照タイプが基準プロパティとメソッドの別のタイプから継承するためにプロトタイプチェーンのプロトタイプを使用することです。コンストラクタ、プロトタイプと例の間の関係の簡単なレビュー:各コンストラクタ関数は、プロトタイプオブジェクトを有する、プロトタイプオブジェクトは、コンストラクタを指し示すポインタを含み、インスタンスはプロトタイプオブジェクトへの内部ポインタを含みます。
function Animal(){}
// 常用原型写法
Animal.prototype = {
name: 'animal',
age: '10',
sayName: function(){
console.log(this.name);
}
};
// 继承Animal,实际上就是重写原型
function runAnimal(){}
runAnimal.prototype = new Animal();
runAnimal.prototype.run = function(){
console.log("我会跑!!!");
}
let cat = new runAnimal();
console.log(cat.name); // 输出 animal
console.log(cat.run()); // 输出 我会跑!!!
复制代码
我々は、すべての参照型はデフォルトのオブジェクトによって継承されていることを知って、これは達成するために、プロトタイプチェーンを通じて継承されます。したがって、上記の継承図に変換することができます。
原型継承
サブクラスのプロトタイプ、親クラスのオブジェクトインスタンス
基本的な考え方:参照型は参照プロパティとメソッドの別のタイプから継承するためにプロトタイプを使用しています。サブクラスによりプロトタイプの親クラスのプロトタイプの例。
function Animal(){
this.behavior = ['吃饭', '睡觉'];
}
// 常用原型写法
Animal.prototype = {
name: 'animal',
age: '10',
sayName: function(){
console.log(this.name);
}
};
// 继承Animal,实际上就是重写原型、原型实例化父类
function runAnimal(){}
runAnimal.prototype = new Animal();
runAnimal.prototype.run = function(){
console.log("我会跑!!!");
}
let cat = new runAnimal();
console.log(cat.name); // 输出 animal
console.log(cat.run()); // 输出 我会跑!!!
console.log(cat.behavior); // ["吃饭", "睡觉"]
let dog = new runAnimal();
dog.behavior.push('咆哮');
console.log(dog.behavior); // ["吃饭", "睡觉", "咆哮"]
console.log(cat.behavior); // ["吃饭", "睡觉", "咆哮"] =>关注点
复制代码
短所:
- サブクラスのサブクラスのインスタンスは、共通の属性に親クラスのプロトタイプのコンストラクタを継承して変更することは、直接他のサブクラスに影響を与えます。
- インスタンスのサブタイプを作成する際に、スーパータイプのコンストラクタにパラメータを渡すことができません。実際には、ない方法は、スーパータイプのコンストラクタパスパラメータに、すべてのオブジェクトインスタンスに影響を与えずには存在しないと述べたする必要があります。
コンストラクタの継承
基本的な考え方は、スーパータイプの内部サブタイプのコンストラクタで、コンストラクタを呼び出すことであるという、非常に簡単です。関数がちょうどそう(適用使用することにより、特定の環境でコードを実行するオブジェクト)と呼び出し()メソッドは、新しく作成された(将来的に)オブジェクトにコンストラクタで実行することができます、忘れないでください。
// 父类
function Animal(id){
this.behavior = ['吃饭', '睡觉'];
this.id = id;
}
Animal.prototype = {
name: 'animal',
age: '10',
sayName: function(){
console.log('我的编号是:'+this.id);
}
};
// 声明子类
function childAnimal(id){
// 继承父类
Animal.call(this, id);
}
let cat = new childAnimal(100);
console.log(cat.id); // 输出 100
console.log(cat.behavior); // ["吃饭", "睡觉"]
console.log(cat.name); // undifined =>关注点
console.log(cat.sayName()); // error!!! =>关注点
let dog = new childAnimal(101);
dog.behavior.push('咆哮');
console.log(dog.id); // 输出 101
console.log(dog.behavior); // ["吃饭", "睡觉", "咆哮"]
console.log(cat.behavior); // ["吃饭", "睡觉"] =>关注点
复制代码
長所と短所
- 借入コンストラクタでは、スーパータイプのサブタイプのコンストラクタで、コンストラクタにパラメータを渡すことができます大きな利点があります。
- サブタイプに対して、スーパータイプのプロトタイプで定義されたメソッドが表示されていない、すべての種類の結果は、コンストラクタのモードを使用することができます。
継承の組み合わせ
これは、継承モードの長いものを再生どちらも、技術の組み合わせを意味し、コンストラクタにプロトタイプチェーンを借ります。その背後にある考え方は、プロトタイプ実装の継承チェーンのプロパティとメソッドのプロトタイプであり、借りコンストラクタによって継承されたインスタンスの属性を達成するために。
// 父类
function Animal(id){
this.behavior = ['吃饭', '睡觉'];
this.id = id;
}
Animal.prototype = {
name: 'animal',
age: '10',
sayName: function(){
console.log('我的编号是:'+this.id);
}
};
// 声明子类
function childAnimal(id){
// 构造函数继承父类
Animal.call(this, id);
}
// 子类的原型对象实例父类
childAnimal.prototype = new Animal();
let cat = new childAnimal(100);
console.log(cat.id); // 输出 100
console.log(cat.behavior); // ["吃饭", "睡觉"]
console.log(cat.name); // animal =>关注点,区别之处
console.log(cat.sayName()); // 我的编号是: 100 =>关注点,区别之处
let dog = new childAnimal(101);
dog.behavior.push('咆哮');
console.log(dog.id); // 输出 101
console.log(dog.behavior); // ["吃饭", "睡觉", "咆哮"]
console.log(cat.behavior); // ["吃饭", "睡觉"] =>关注点
复制代码
長所と短所
- 継承と回避借入コンストラクタのプロトタイプチェーンの欠陥の組み合わせは、その利点を組み合わせ、JavaScriptは継承の最も一般的に使用されるモードになっています。さらに、のinstanceofとisPrototypeOf()また、合成継承に基づいて作成されたオブジェクトを識別するために使用することができます。
- サブタイプのプロトタイプを作成する際に、一度、と一度サブタイプコンストラクタの内部:最大の問題はどのような場合、スーパーコンストラクタの2種類を呼び出して、継承の組み合わせです。
原型継承
原型継承アイデアは、既存のオブジェクトに基づいてプロトタイプを用いて新しいオブジェクトを作成することですが、また、そのためのカスタムタイプを作成する必要はありません。
// 道格拉斯·克罗克福德给出的函数
function object(o){
function F(){}
F.prototype = o;
return new F();
}
复制代码
それらの入ってくるオブジェクトの簡易コピーを実行するための基本的に、オブジェクト()。
function book(obj) {
function F(){};
F.prototype = obj;
return new F();
}
let HTML5 = {
name: 'HTML5 高级程序设计',
author: ['Peter Lubbers', 'Ric Smith', 'Frank Salim']
};
let myNewBook = new book(HTML5);
console.log(myNewBook.name); // HTML5 高级程序设计
myNewBook.author.push('Brian Albers');
console.log(myNewBook.author); // ["Peter Lubbers", "Ric Smith", "Frank Salim", "Brian Albers"]
let otherBook = new book(HTML5);
otherBook.name = "VUE";
otherBook.author.push('尤');
console.log(otherBook.name); // VUE
console.log(otherBook.author); // ["Peter Lubbers", "Ric Smith", "Frank Salim", "Brian Albers", "尤"]
console.log(myNewBook.author); // ["Peter Lubbers", "Ric Smith", "Frank Salim", "Brian Albers", "尤"]
复制代码
長所と短所
- 親クラスのオブジェクトブック属性値の型が割り当てられ、参照型属性は、一般的に使用されています。リファレンスtype属性の値は常に同じプロトタイプのモードを使用して、対応する値を共有します。
寄生継承
寄生は、アイデアや寄生コンストラクタを継承し、工場出荷時のパターンは、オブジェクトを強化するために、いくつかの方法で、内部機能、機能をカプセル化するため、連続プロセスの作成のみを類似しており、最終的にはそれが本当に同じように、すべての作業を行うのが好きさオブジェクトを返します。
function createAnother(original){
var clone = object(original); //通过调用函数创建一个新对象
clone.sayHi = function(){ //以某种方式来增强这个对象
console.log("hi");
};
return clone; //返回这个对象
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); //"hi"
复制代码
組み合わせ寄生継承
いわゆる寄生複合遺伝、すなわち、遺伝型プロトタイプチェーンをブレンドするコンストラクタメソッドを借り属性を継承します。その背後にある基本的な考え方は次のとおりです。プロトタイプの型のサブタイプを指定し、スーパーコンストラクタを呼び出す必要はありません、我々は唯一のスーパータイプのプロトタイプのコピー以上のものを必要としません。本質的には、スーパータイプのプロトタイプを継承して、プロトタイプのサブタイプに結果を割り当てる寄生継承を使用することです。
// 定义父类
function SuperClass (name){
this.name = name;
this.colors = ["red","blue","green"];
}
// 定义父类原型方法
SubClass.prototype.getName = function () {
console.log(this.name);
}
// 定义子类
function SubClass (name, time){
SuperClass.call (this, name); // 构造函数式继承
this.time = time; // 子类新增属性
}
function inheritPrototype(subType, superType){
var prototype = object(superType.prototype); // 创建对象
prototype.constructor = subType; // 增强对象
subType.prototype = prototype; // 指定对象
}
// 寄生式继承父类原型
inheriPrototype(SubClass, SuperClass);
// 子类新增原型方法
SubClass.prototype.getTime = function (){
console.log(this.time);
};
// 创建两个测试方法
var instance1 = new SubClass("js book", 2018);
var instance2 = new SubClass("css book", 2019);
instance1.colors.push("black");
console.log(instance1.colors); // ["red","blue","green","black"]
console.log(instance2.colors); // ["red","blue","green"]
instance2.getName (); // css book
instance2.getTime (); // 2019
复制代码
概要
自身の小さな赤い本にゆっくりと基本的にプロトタイプがひどく書かれ、理解することができ、手動でコードをノックして、もう一度それを読んで、私を修正してください。プロトタイプ、プロトタイプチェーン、個人的な感情が混合されたプロトタイプ継承は、試作品を入れて、それはプロトタイプチェーン、プロトタイプ継承を配置します。自分自身を参照するには10倍、より良いコードの思い出がより深い問題になるノックも(たとえば、あなたは多くの場合、問題にこのポイントを使用する)あなたが輝く作る途中で登場。
参考資料
- JavaScriptの高度なプログラミング(第3版)
ます。https://juejin.im/post/5cef3b3b518825526b294b6bで再現