【JavaScript】-繼承
阿新 • • 發佈:2019-01-12
前言
說起繼承,情不自禁的會想起封裝和多型,那我在這裡簡單闡述一下多型和封裝,後面我們重點說JS怎麼實現的繼承。
封裝:可以稱為包裝,一堆重複的程式碼放在一個函式中,用的時候直接調取。一系列類似的方法放在一個物件中。
多型:一個物件有不同的行為,或者同一個行為針對不同的物件,產生不同的結果。
繼承
首先我先說明一點,JavaScript不是一門面向物件的語言,JavaScript是一門基於對相關的語言,JavaScript可以通過建構函式來模擬class來實現。舉個栗子:
<script> //動物有名字,有體重,有吃東西的行為 //小狗有名字,有體重,有毛色,有吃東西的行為,還有要人的行為 //哈士奇名字,有體重,有毛色,性別,有吃東西的行為,咬人的行為,逗主人開心的行為 //動物的建構函式 function Animal(name,weight) { this.name = name; this.weight = weight; } //動物的原型的方法 Animal.prototype.eat = function () { console.log("天天吃東西,就是吃"); } //狗的建構函式 function Dog(color) { this.color = color; } Dog.prototype = new Animal("哮天犬", "50kg"); Dog.prototype.bitePerson = function () { console.log("汪汪 ~~咬死你"); }; //哈士奇 function ErHa(sex) { this.sex = sex; } ErHa.prototype = new Dog("黑白色"); ErHa.prototype.playHost = function () { console.log("拆家 ... 開心不 .. 驚喜不 .."); }; var erHa = new ErHa("雄性"); console.log(erHa.name, erHa.weight, erHa.color); erHa.eat(); erHa.bitePerson(); erHa.playHost(); </script>
最後的輸出結果為:
解釋一下這個例子:有個動物的建構函式,動物有自己的原型物件。有個狗的建構函式,狗的例項物件改變了指向,指向了動物的原型物件。有個二哈的建構函式,二哈的例項物件指向了狗的例項物件,所以二哈有了所有的方法。是不是和原型很像,沒錯繼承的本質就是原型。
借用建構函式來繼承
<script> function person(name,age,sex,weight) { this.name = name; this.age = age; this.sex = sex; this.weight = weight; } person.prototype.sayhi = function () { console.log("您好"); } function student(name,age,sex,weight,score) { //借用建構函式 person.call(this, name, age, sex, weight); this.score = score; } var stu1 = new student("小明", 10, "10kg", "110"); console.log(stu1.name, stu1.age, stu1.sex, stu1.weight, stu1.score); var stu2 = new student("小換", 11, "11kg", "120"); console.log(stu2.name, stu2.age, stu2.sex, stu2.weight, stu2.score); var stu3 = new student("小畫", 12, "12kg", "130"); console.log(stu3.name, stu3.age, stu3.sex, stu3.weight, stu3.score); </script>
借用建構函式實現繼承,主要的程式碼就是:
function student(name,age,sex,weight,score) {
//借用建構函式
person.call(this, name, age, sex, weight);
this.score = score;
}
本來student中是沒有name,age,sex,weight這些屬性的。那就需要Call這個方法來‘借’,借過來就是自己了,就可以使用了。但是它有個致命的缺陷就是方法借不過來!那麼就有了組合繼承。
組合繼承
組合繼承=原型繼承+借用建構函式繼承
<script>
//組合繼承:原型繼承+借用建構函式繼承
function person(name,age,sex) {
this.name = name;
this. age = age;
this.sex = sex;
}
person.prototype.sayHi = function () {
console.log("qwer");
};
function student(name,age,sex,score) {
//借用建構函式
person.call(this, name, age, sex);
this.score = score;
}
//改變原型指向
student.prototype = new person();
student.prototype.eat = function () {
console.log("吃東西");
};
var stu = new student("小阿斯頓", 20, "男", "100");
console.log(stu.name, stu.age, stu.sex, stu.score);
stu.sayHi();
stu.eat();
</script>
執行結果為:
我們通過借構成函式來實現屬性的繼承,通過改變原型的指向來繼承方法。
拷貝繼承
拷貝繼承:那一個物件中的屬性或者方法複製到另一個物件中
function person() {
}
person.prototype.age = 10;
person.prototype.sex="男";
person.prototype.height = 100;
person.prototype.play = function () {
console.log("玩得好開心");
}
var obj2 = {};
//person 的構造中有原型prototype,prototype就是一個物件,那麼裡面age,sex,height,play都是改物件中的屬性或者方法
for (var key in person.prototype) {
obj2[key] = person.prototype[key];
}
console.log(obj2.age, obj2.sex, obj2.height, obj2.play());
改變原型指向是棧裡的兩個物件指向堆裡一個地址。拷貝繼承是在堆裡開闢一個新的空間,兩個物件分別指向自己的地址。
總結
對,沒錯。繼承的本質就是原型。