オブジェクト指向プログラミングオブジェクト指向の継承のJAVASCRIPT
オブジェクト指向プログラミングの重要な特徴は、オブジェクトAとオブジェクトB継承、オブジェクトBが動作(メソッド)及び状態(属性)を持つことができ、継承されたコードの再利用を促進します。
(JavaScript言語によって継承された「プロトタイプオブジェクト」prototype
を達成するためには)、ES6は(クラスが導入されましたclass
)、参照してくださいES6エントリを。
プロトタイプオブジェクトの概要
1.1欠点コンストラクタ
プロトタイプオブジェクトを再訪する前には、コンストラクタを見てください。
JavaScriptはオブジェクトインスタンスのコンストラクタ内で定義されたコンストラクタ、プロパティおよびメソッドを介して新たなオブジェクトを生成することができ、コンストラクタによって生成される各新しいオブジェクトが同じ特性および挙動を有します。
function Animal(age, name){
if(!(this instanceof Animal)){
return new Animal(age, name);
}
this.age = age;
this.name = name;
this.print = function(){
console.log(this.name);
}
}
var a1 = new Animal(2, "dog");
var a2 = new Animal(3, "cat");
// 通过构造函数生成的实例对象,都有age,name和print属性
a1; // {age: 2, name: "dog", print: ƒ}
a2; // {age: 3, name: "cat", print: ƒ}
上記の例では、各動物が名前を持つ独自の年齢を持ち、問題はないようです。上記の例に基づいてI、摂食行動、睡眠に動物を追加します。
function Animal(age, name){
if(!(this instanceof Animal)){
return new Animal(age, name);
}
this.age = age;
this.name = name;
this.print = function(){
console.log(this.name);
};
this.sleep = function(){
console.log("睡觉!");
};
this.eat = function(){
console.log("吃东西!")
};
}
var a1 = new Animal(2, "dog");
var a2 = new Animal(3, "cat");
a1.sleep(); // 睡觉
a2.sleep(); // 睡觉
a1.eat(); // 吃东西
a2.eat(); // 吃东西
// 都具有吃东西和睡觉的行为,那么两者一样吗?
a1.sleep === a2.sleep; // false
a1.eat === a2.eat; // false
私たちは、上記の例から見る、a1
とa2
持っているeat
とsleep
方法が、二つは同じではありません。これが原因であるeat
とsleep
オブジェクトのすべてのインスタンス上で生成され、2つのインスタンスが2回発生しています。すなわち、それぞれの新しいインスタンス、新しい都市の作成eat
とsleep
メソッドを。だから、すべてのため、より多くの、システムリソースの無駄ということeat
と、sleep
メソッドが同じ行動している、各インスタンスは共有されなければなりません。
これは(「プロトタイプオブジェクト」を介し得るprototype
べき解決します)。
1.2 prototypeプロパティ
JavaScriptの継承メカニズムのデザインのアイデアは、プロトタイプオブジェクトのすべてのプロパティとメソッドは、オブジェクトの共有をインスタンス化することができるということです。
JavaScriptは、各機能を有していることを提供するprototype
オブジェクトへのプロパティ、ポイント。
function f(){}
typeof f.prototype; // "object"
上記のコードでは、関数がf
有するデフォルトprototype
オブジェクトに属性を。
コンストラクタのために、生成されたインスタンスの属性が自動的にオブジェクトインスタンスの原型となっているとき。
function Animal(name){
this.name = name;
}
// 原型对象设置公共的属性sex
Animal.prototype.sex = 1 ;
typeof Animal.prototype; // "object"
var a1 = new Animal("cat");
var a2 = new Animal("dog");
a1.sex; // 1
a2.sex; // 1
上記コードは、コンストラクタAnimal
のprototype
オブジェクトのプロパティがあること、を指摘し、a1
そしてa2
プロトタイプオブジェクトは、上記追加するプロトタイプオブジェクトにsex
プロパティを、オブジェクト・インスタンスを共有することができるsex
属性。
プロトタイプオブジェクトのインスタンスのプロパティは、オブジェクト自体のプロパティではありません。限り変性プロトタイプオブジェクトとして、変更はすぐにオブジェクトのすべてのインスタンスに反映されるであろう。
// 原型对象修改sex
Animal.prototype.sex = 0 ;
// 每个实例的sex发生改变
a1.sex; // 0
a2.sex; // 0
例として、オブジェクト自体はプロパティやメソッドでない場合は、このプロパティまたはメソッドを見つけるために、プロトタイプオブジェクトに移動します。オブジェクトのプロパティまたはメソッド自体のインスタンスがある場合は、このプロトタイプオブジェクトのプロパティやメソッドを探しに行くことはありません。
a1.sex = 2;
a1.sex; // 2
a2.sex ; // 0
Animal.prototype.sex; // 0
要約すると、プロトタイプオブジェクトの役割は、オブジェクトのすべてのインスタンスによって共有されるプロパティとメソッドを定義することです。
1.3プロトタイプチェーン
JavaScriptは、すべてのオブジェクトが独自のプロトタイプオブジェクト(持っていることを提供しますprototype
)。一方、任意のオブジェクトが他のオブジェクトのプロトタイプとして機能することができ、一方、プロトタイプオブジェクトはオブジェクトであるため、それはまた、独自のプロトタイプを持つように。従って、「プロトタイプチェーン」を形成するであろう。その後、オブジェクトプロトタイプに、プロトタイプのプロトタイプとを......
層をトレースした場合、すべてのオブジェクトのプロトタイプは、最終的に遡ることができObject.prototype
、そのObject
コンストラクタprototype
オブジェクトを指すことプロパティ。つまり、すべてのオブジェクトが継承するObject.prototype
プロパティを。
実際には、Object.prototype
また、独自のプロトタイプ、そのプロトタイプを持っていますnull
。null
私たちは、任意のプロパティとメソッドを持って、自分ではないプロトタイプをしません。したがって、プロトタイプチェーンは末端にありますnull
。
Object.getPrototypeOf(Object.prototype); // null
下記に示すように、プロトタイプチェーンを完了するために:
オブジェクトの属性を読み込む場合、オブジェクト自体のプロパティを見つけ、そうでない場合は、これが失敗した場合、そのプロトタイプに進むためのJavaScriptエンジンは、プロトタイプの試作品に進学します。トップレベルの場合まではObject.prototype
まだ見つけることができない、そして返しますundefined
。オブジェクト自体とそのプロトタイプは、同じ名前のプロパティを定義した場合、優先順位は、オブジェクト自身のプロパティを読んで、これは「カバー」と呼ばれています。
注:プロトタイプチェーンのプロパティを探して、性能が影響する、プロトタイプチェーンの上流に複数のプロパティ、大きなパフォーマンスへの影響。あなたが存在しないプロパティを見つけた場合、それは全体のプロトタイプチェーンを横断します。
1.4 constructorプロパティ
prototype
オブジェクトが持っているconstructor
デフォルトに指して、プロパティをprototype
コンストラクタオブジェクトが配置されています。
function P() {}
P.prototype.constructor === P // true
constructor
プロパティも定義しprototype
、すべてのオブジェクトのインスタンスを継承することができることが意図されている、上記目的を。
function F(){}
var f1 = new F();
//prototype对象的constructor属性默认指向prototype对象所在的构造函数
f1.constructor === F; // true
f1.constructor === F.prototype.constructor; // true
その後、constructor
プロパティがどのような効果を持っていますか?
constructor
プロパティコンストラクタを生成端インスタンスオブジェクトに決定されます。
function F(){}
var f1 = new F();
f1.constructor;//F(){}
constructor
財産、オブジェクトの新しいインスタンスは、オブジェクトの別のインスタンスことができます。
function F(){}
var f1 = new F();
// 通过constructor属性新建另一个实例对象
var f2 = new f1.constructor();
f2 instanceof F; // true
constructor
プロパティは、プロトタイプオブジェクトを変更した場合、プロトタイプオブジェクトのコンストラクタとの関係を示しているが、また、一般的な修正constructor
引用された間違った時間を防ぐ性質を。
function F(){};
F.prototype.constructor === F; // true
// 修改原型对象为一个数组对象
F.prototype = new Array();
F.prototype.constructor === F; // false
F.prototype.constructor === Array; // true
上記のコードは、修飾F
プロトタイプオブジェクトではなく、変更constructor
をもたらす特性を、constructor
特性がもはや導かれませんF
。
プロトタイプオブジェクトを変更するとき、好ましくは修飾constructor
プロパティ。
function F(){}
// 不推荐写法,没有修改contructor属性
F.prototype = {
method1: function (...) { ... },
...
}
// 推荐写法,constructor属性重新指向原来的构造函数
F.prototype = {
constructor: F,
method1: function (...) { ... },
...
}
// 更好的写法,只在原型对象上面添加方法
F.prototype.method1 = function(...){...}
2. instanceof演算子
instanceof
オペレータは、オブジェクトコンストラクタのインスタンスであるかどうかを示すブール値を返します。instanceof
左操作者がオブジェクトのインスタンスであり、右側がコンストラクタです。
var v = new Vehicle();
v instanceof Vehicle // true
instanceof
オペレータはかなりのものである:オブジェクトインスタンスの左側に右のプロトタイプオブジェクトコンストラクタのプロトタイプチェーンかどうかを確認してください。したがって、次の2つは同じ言い回しです。
function F(){}
var f = new F();
f instanceof F; // true
//等价于
F.prototype.isPrototypeOf(f); // true
ためinstanceof
のチェックがチェーン全体をプロトタイプオブジェクトの同じインスタンスは、コンストラクタの複数戻すことができますtrue
。
var now = new Date();
now instanceof Date; // true
now instanceof Object; // true
// 等价于
Date.prototype.isPrototypeOf(now);
Object.prototype.isPrototypeOf(now);
instanceof
オペレータが使用するタイプ判定値にすることができます。
var person = {
name: "jidi",
age: 22
}
var arrays = ["I","love","java"];
person instanceof Object; // true
arrays instanceof Array; // true
instanceof
オペレータが使用することができる非の値か否かが判断されるnull
すべてのオブジェクトがあるので、オブジェクトObject
を除いて、インスタンスnull
。
var person = {
name: "jidi",
age: 22
}
// 判断一个值是否是非null对象
person instanceof Object; // true
null instanceof Object; // false
注:instanceof
オペレータは、オブジェクトのみに使用することができ、元の型の値が適用されません。しかし、また、ためnull
とundefined
常に返しますfalse
。
3.継承コンストラクタ
遅すぎる、私はライトバックする時間を持って、立ち上がることができませんでした...