深入理解javascript原型繼承
什麼是面向對象?
在基於類的面向對象方式中,對象(object)依靠類(class)來產生。
而在基於原型的面向對象方式中,對象(object)則是依靠 構造器(constructor)利用 原型(prototype)構造出來的。
生成對象的方式
1,聲明對象字面量:JSON
var obj = {
name: "jack",
eat: "bread"
}
console.log(typeof obj);
2,使用構造函數生成一個新的對象
//構造函數
var Foo = function(name){
this.name = name; //私有屬性
}
//原型方法和屬性,被繼承時候纔會調用
Foo.prototype.run = function(){
alert("I'm running so fast that can't stop at all!");
}
var kick = new Foo("kick");
console.log(typeof kick);
console.log(kick.name);
kick.run();
3,使用使用Object.create創建對象
var Point = {
x: 0,
y: 0,
print: function () { console.log(this.x, this.y); }
};
var p = Object.create(Point); //new一個對象
p.x = 10;
p.y = 20;
p.print(); // 10 20
這個看起來很簡潔,而且能夠完全代替new的用法,畢竟new關鍵字並不真正的屬於JavaScrip的原型模式.它先是聲明瞭一個構造器,然後將其原型設置爲你想要的值,最後返回生成的新對象.其實就是封裝了new.
Object.create = function (parent) {
function F() {}
F.prototype = parent;
return new F();
};
JavaScrip原型鏈(prototype chain)
JavaScrip可以採用構造器(constructor)生成一個新的對象,每個構造器都擁有一個prototype屬性,而每個通過此構造器生成的對象都有一個指向該構造器原型(prototype)的內部私有的鏈接(proto),而這個prototype因爲是個對象,它也擁有自己的原型,這麼一級一級指導原型爲null,這就構成了原型鏈.
原型鏈的工作原理
function getProperty(obj, prop) {
if (obj.hasOwnProperty(prop)) //首先查找自身屬性,如果有則直接返回
return obj[prop]
else if (obj.__proto__ !== null)
return getProperty(obj.__proto__, prop) //如何不是私有屬性,就在原型鏈上一步步向上查找,直到找到,如果找不到就返回undefind
else
return undefined
}
// 聲明 Animal 對象構造器
function Animal(name) {
this.name = name;
}
// 將 Animal 的 prototype 屬性指向一個對象,
// 亦可直接理解爲指定 Animal 對象的原型
Animal.prototype = {
weight: 0,
eat: function() {
alert( "Animal is eating!" );
}
}
// 聲明 Mammal 對象構造器
function Mammal() {
this.name = "mammal";
}
// 指定 Mammal 對象的原型爲一個 Animal 對象。
// 實際上此處便是在創建 Mammal 對象和 Animal 對象之間的原型鏈
Mammal.prototype = new Animal("animal");
// 聲明 Horse 對象構造器
function Horse( height, weight ) {
this.name = "horse";
this.height = height;
this.weight = weight;
}
// 將 Horse 對象的原型指定爲一個 Mamal 對象,繼續構建 Horse 與 Mammal 之間的原型鏈
Horse.prototype = new Mammal();
// 重新指定 eat 方法 , 此方法將覆蓋從 Animal 原型繼承過來的 eat 方法
Horse.prototype.eat = function() {
alert( "Horse is eating grass!" );
}
// 驗證並理解原型鏈
var horse = new Horse( 100, 300 );
console.log( horse.__proto__ === Horse.prototype );
console.log( Horse.prototype.__proto__ === Mammal.prototype );
console.log( Mammal.prototype.__proto__ === Animal.prototype );
//原型鏈
Horse-->Mammal的實例
Mammal-->Animal的實例
Animal -->Object.prototype