// 定義一個動物類
function Animal (name) {
// 屬性
this.name = name || 'Animal';
// 實例方法
this.sleep = function(){
console.log(this.name + '正在睡覺寻歧!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
函數(shù)里this的屬性 和 函數(shù)外prototype的屬性,在new之后秩仆,都會被子類繼承
function Cat(){
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// Test Code
var cat = new Cat();
console.log(cat.name); //cat
console.log(cat.eat('fish')); //cat正在吃:fish
console.log(cat.sleep()); //cat正在睡覺码泛!
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
需要注意的是,原型鏈的繼承方式澄耍,創(chuàng)建子類時噪珊,無法像父類構(gòu)造傳參,而且來自原型對象的引用屬性是所有實例共享的逾苫,測試代碼如下
function Animal (name) {
// 屬性
this.name = name || 'Animal';
// 實例方法
this.sleep = function(){
console.log(this.name + '正在睡覺卿城!');
}
//實例引用屬性
this.features = [];
}
function Cat(name){
}
Cat.prototype = new Animal();
var tom = new Cat('Tom'); //創(chuàng)建子類的時候傳參數(shù),看下面輸出铅搓,有沒有效果
var kissy = new Cat('Kissy');
console.log(tom.name); // "Animal" 說明傳參沒有效果
console.log(kissy.name); // "Animal"
console.log(tom.features); // []
console.log(kissy.features); // []
tom.name = 'Tom-New Name';
tom.features.push('eat');
//針對父類實例值類型成員的更改,不影響
console.log(tom.name); // "Tom-New Name"
console.log(kissy.name); // "Animal"
//針對父類實例引用類型成員的更改搀捷,會通過影響其他子類實例
console.log(tom.features); // ['eat']
console.log(kissy.features); // ['eat']
原因分析:
關(guān)鍵點:屬性查找過程
執(zhí)行tom.features.push星掰,首先找tom對象的實例屬性(找不到),
那么去原型對象中找嫩舟,也就是Animal的實例氢烘。發(fā)現(xiàn)有,那么就直接在這個對象的
features屬性中插入值家厌。
在console.log(kissy.features); 的時候播玖。同上,kissy實例上沒有饭于,那么去原型上找蜀踏。
剛好原型上有维蒙,就直接返回,但是注意果覆,這個原型對象中features屬性值已經(jīng)變化了颅痊。
function Animal(name){
this.name=name
}
Animal.prototype.eat = function(food){
console.log(this.name + '吃' + food)
}
function Cat(){}
Cat.prototype = new Animal();
Cat.prototype.name = '貓';
let final = new Cat();//無法在這里像父類傳參
final.eat('魚') // 輸出 "貓吃魚"