title: 面向對象(八)繼承___ 03原型鏈繼承 # 文章頁面上的顯示名
date: # 文章生成時間,一般不改
categories: # 文章分類目錄,可省略
- 面向對象
tags: # 文章標簽,可省略
- 面向對象
- 基于原型面向對象的繼承 # 個數不限,單個可直接跟在 tags 后面
原型鏈結構
01 每個對象都是由構造函數創建出來的,因為每個對象都有構造函數
02 每個構造函數都有一個與之對應的原型對象
03 原型對象本身也是對象
04 因此,原型對象也有自己的構造函數
05 原型對象的構造函數也有自己的原型對象
06 原型對象的構造函數的原型對象也是對象,所以它也有自己的構造函數
07 原型對象的構造函數的原型對象的構造函數也有自己的原型對象。。。
以上,形成一個鏈式的結構,就稱為是原型鏈
原型鏈的頂端是** Object.prototype**,Object.prototype本身也是一個對象,因此也有原型對象
Object.prototype.proto 是null
原型鏈中對象屬性的搜索規則 --- 就近原則
01對象.屬性的方法去訪問屬性的時候,先查找有沒有對應的實例屬性,如果有那么就直接使用
02如果沒有,那么就去該對象的原型對象上面去找,如果有那么就直接使用
03如果沒有,那么就接著查找原型對象的原型對象,如果有,那么就直接使用,
04如果沒有,那么就繼續上面的搜索過程
05直到搜索到Object.prototype為止,如果還是沒有找到就返回undefined或者是報錯
注意:
原型鏈搜索的路徑越長,查詢屬性所花費的時間就越多
原型鏈繼承
-
原型鏈繼承的步驟
- 01提供一個父構造函數
- 02 提供一個子構造函數
- 03 設置子構造函數的原型對象為父構造函數的一個實例對象
- 04 在實例對象上面設置屬性和方法
<script>
function A(){
this.age = 55;
this.showAge = function(){
console.log(this.age);
}
};
//設置A的原型屬性和方法
A.prototype.logDes = function(){
console.log("des");
}
function B(){};
//設置原型鏈繼承
B.prototype = new A();
B.prototype.des = "des";
B.prototype.show = function(){
console.log("show");
};
var b1 = new B();
console.log(b1.age);
b1.showAge();
b1.logDes();
console.log(b1);
</script>
復雜原型鏈繼承示例
<script>
//01 提供構造函數(4)
//02 設置屬性和方法(建議:屬性設置在實例上,方法設置在原型上)
//03 設置繼承
//04 修正構造器屬性
Animal.prototype.run = function(){
console.log("run");
}
function Animal(color){
this.color = color
}
Person.prototype = new Animal();
Person.prototype.eat = function(){
console.log("chi");
}
Person.prototype.constructor = Person;
function Person(){
this.name = "默認的名稱"
}
Student.prototype = new Person();
Student.prototype.study = function(){
console.log("good good study, day day up");
}
Student.prototype.constructor = Student;
function Student(){
this.id = "201701"
}
Boy.prototype = new Student();
Boy.prototype.lol = function(){
console.log("lol");
}
Boy.prototype.constructor = Boy;
function Boy(){
this.sex = "男"
}
//創建對象
var boy = new Boy("紅色");
console.log(boy);
</script>
原型鏈的使用注意
01 在設置完原型鏈之后需要修正構造器屬性的指向(Student.prototype.constructor)
02 要在設置完原型繼承之后再來為原型對象添加屬性和方法
03 要在設置完原型繼承之后只能通過對象的動態特性來設置原型對象的屬性和方法,不要使用字面量的方式
原型鏈繼承的問題
01 無法對父構造函數傳遞參數
02 繼承過來的實例屬性會成為當前對象的原型屬性,會被創建出來的多個對象所共享
<script>
function Person(name,age){
this.name = name;
this.age = age;
this.friends = ["王小強"];
}
Person.prototype.showAge = function(){
console.log(this.age);
}
Person.prototype.showName = function(){
console.log(this.name);
}
function Boy(book){
this.book = book;
};
//設置繼承
Boy.prototype = new Person();
var boy01 = new Boy("三字經");
var boy02 = new Boy("弟子規");
console.log(boy01);
console.log(boy02);
console.log(boy01.friends);
console.log(boy02.friends);
boy01.friends.push("張空空");
console.log(boy01.friends);
console.log(boy02.friends);
</script>