繼承
描述
- 在一個構造函數或對象中定義的屬性或方法,能夠在另外一個構造函數或對象中直接使用,而不須要在去從新定義
原型鏈
- 一個構造函數或對象的原型指向另外一個構造函數或對象,以此類推造成一條鏈狀結構,這種效果被稱爲原型鏈
- 這種原型鏈也能夠稱爲 繼承
/* 定義第一個構造函數 */
function A(){
this.a = 'a';
}
/* 建立對象 */
var a = new A();
/* 定義第二個構造函數 */
function B(){
this.b = 'b';
}
/* 將B的原型指向對象a */
B.prototype = a;
/* 建立對象 */
var b = new B();
console.log( b.b );// 顯示 b
console.log( b.a );// 顯示 a
/* 定義第三個構造函數 */
function C(){
this.c = 'c';
}
/* 將C的原型指向對象b */
C.prototype = b;
/* 建立對象 */
var c = new C();
console.log( c.c );// 顯示 c
console.log( c.b );// 顯示 b
console.log( c.a );// 顯示 a
只繼承於原型
- 一個構造函數的原型指向另外一個構造函數的原型
- 能夠理解爲原型鏈的一種優化(我的理解)
/* 定義第一個構造函數 */
function A(){
// 將自有屬性改寫爲原型屬性
// this.a = 'a';
}
A.prototype.a = 'a';
/* 定義第二個構造函數 */
function B(){
// this.b = 'b';
}
/* 將B的原型指向A的原型 */
B.prototype = A.prototype;
/*
將B的自有屬性改寫成原型屬性
* 要先去執行原型的指向
* 在去改寫屬性
* 若是代碼的執行順序反過來會變成對屬性的從新賦值
*/
B.prototype.b = 'b';
/* 定義第三個構造函數 */
function C(){
this.c = 'c';
}
/* 將C的原型指向B的原型 */
C.prototype = B.prototype;
/* 建立對象 */
var c = new C();
console.log(c.c);// 顯示 c
console.log(c.b);// 顯示 b
console.log(c.a);// 顯示 a
原型式繼承
- 定義一個函數,在該函數中建立一個構造函數,再將構造函數建立的對象返回,用於實現繼承
/* 定義一個函數 */
function fun( obj, values ) {
/* 定義一個構造函數 */
function Fn() {
/* 遍歷構造函數的屬性和方法 */
for ( var key in values ) {
this[key] = values[key];
}
}
/* 將函數的參數當作構造函數的原型 */
Fn.prototype = obj;
/* 將構造函數建立的對象作爲函數的返回值 */
return new Fn();
}
/* 定義一個對象 */
var obj = {
name : '唐三'
}
/* 調用函數 - 將構造函數的自有屬性或方法以參數傳入 */
var f = fun( obj, {
nian : 20,
menpai : function () {
console.log( '唐門' );
}
} );
/* 調用屬性和方法 */
console.log( f.name );// 顯示 唐三
console.log( f.nian );// 顯示 20
f.menpai();// 顯示 唐門
Object.create()方法
- 使用Object.create()方法也能夠實現繼承
/* 定義一個對象 */
var obj1 = {
name : '融念冰'
}
var s = Object.create( obj1, {
/* 定義屬性或方法時,值須要以對象的形式表示 */
nian : {
value : 20
}
} );
/* 調用屬性 */
console.log( s.name );// 顯示 融念冰
console.log( s.nian );// 顯示 20
藉助構造函數
- 可用過在子級的構造函數中調用父級的構造函數,來實現繼承效果
/* 定義父級構造函數 */
function Fun() {
/* 這裏的this指向調用的參數 */
this.fuji = '哈哈哈';
}
/* 定義子級構造函數 */
function Fn() {
/* 在子級構造函數中調用父級構造函數中的屬性 */
Fun.apply( this );// 這裏的this指向當前構造函數的對象(構造函數Fn)
/* 這裏的this表示當前調用屬性的對象 */
this.ziji = '呀呀呀';
}
/* 建立子級對象 */
var ziji = new Fn();
console.log( ziji );// 顯示 Fn { fuji: '哈哈哈', ziji: '呀呀呀' }
組合式繼承
- 將原型式繼承和藉助構造函數式繼承有效的結合在一塊兒
- 分開繼承自有屬性和原型屬性
/* 定義父級構造函數 */
function Fun() {
/* 這裏的this指向調用的參數 */
this.name = '唐三';
}
/* 添加原型屬性 */
Fun.prototype.nian = 20;
/* 定義子級構造函數 */
function Fn() {
/* 在子級構造函數中調用父級構造函數中的屬性 - 繼承父級的自有屬性 */
Fun.apply( this );// 這裏的this指向當前構造函數的對象(構造函數Fn)
/* 這裏的this表示當前調用屬性的對象 */
this.menpai = '唐門';
}
/* 繼承父級的原型屬性 */
Fn.prototype = Fun.prototype;
/* 建立子級對象 */
var ziji = new Fn();
/* 調用屬性 */
console.log( ziji.name );// 顯示 唐三
console.log( ziji.nian );// 顯示 20
console.log( ziji.menpai );// 顯示 唐門