構造對象
通過構造函數(shù)(“類”)的方法來實現(xiàn)構造對象
function People(name, age){
this.nick = name;
this.age = age;
this.printName = function(){
console.log(this.nick);
}
}
var p1 = new People('aaar', 30);
var p2 = new People('bbb', 30);
// Person是一個函數(shù),也是對象,相當于“類”。p1、p2為這個對象的實例。
prototype
- 每個函數(shù)(“類”)都自動添加一個名稱為
prototype屬性,這是一個對象 - 每個實例都有一個內(nèi)部屬性
__proto__(規(guī)范中沒有指定這個名稱,但是瀏覽器都這么實現(xiàn)的) 指向其“類”的prototype屬性
二者關系如下圖:
prototype.png
既然prototype相當于公共容器,我們可以把一些重復的函數(shù)方法綁定在prototype上,而只保留參數(shù)部分
function People(name, age){
this.nick = name;
this.age = age;
}
People.prototype.sayName = function(){
console.log(this.nick)
}
var p1 = new People('aaa', 30);
var p2 = new People('bbb', 30);

prototype2.png
原型鏈
既然People是P1、P2的原型,并且P1、P2繼承了People的方法,那么People的原型又是誰呢?
測試.PNG
經(jīng)過測試原型鏈的頂端為0bject,也就是常說的“一切皆為對象的說法”,詳情如下圖:

原型鏈.png
但是對于簡單類型(數(shù)字、字符串、boolean、null、undefined),雖然有一些方法可用,但不是正真的對象,比如無法添加屬性,方法不能改變其本身。。。。。。
繼承
繼承是指一個對象直接使用另一對象的屬性和方法。用于精簡代碼提高性能。
得到一個“類”的屬性
對象屬性的獲取是通過構造函數(shù)的執(zhí)行,我們在一個類中執(zhí)行另外一個類的構造函數(shù),就可以把屬性賦值到自己內(nèi)部,但是我們需要把環(huán)境改到自己的作用域內(nèi),借助函數(shù)call來實現(xiàn)
得到一個“類”的方法
類的方法都定義在了prototype里面,所以只要我們把子類的prototype改為父類的prototype的備份就好了
Child.prototype = Object.create(Father.prototype);
需要注意一點就是對子類添加方法,必須在修改其prototype之后,如果在之前會被覆蓋掉

繼承.png
代碼如下:
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
};
function Man(name, sex, age){
//Person(name, sex); 函數(shù)里面的 this 就是 m
Person.call(this, name, sex);
this.age = age;
}
Man.prototype = Object.create(Person.prototype);
// Object.create為ES5的方法,還可以用以下放方法來實現(xiàn)
// Man.prototype = new Person()
Man.prototype.constructor = Man;
Man.prototype.printAge = function(){
console.log(this.age);
};
var p = new Person('aaa', '男');
var m = new Man('bbb', '男',10)
hasOwnProperty
判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性
m.hasOwnProperty('name'); // true
m.hasOwnProperty('printName'); // false
Male.prototype.hasOwnProperty('printAge'); // true
