一香缺、來源
JavaScript不是真正意義上的面向?qū)ο笳Z言,沒有提供傳統(tǒng)的繼承方式薄疚,它提供的是一種叫做原型繼承的方式
二碧信、原型的作用
最主要的一點(diǎn)是數(shù)據(jù)共享,創(chuàng)建對象的時(shí)候输涕,我們會(huì)把公共的方法和屬性掛載到原型上音婶,實(shí)例可以訪問原型對象上定義的屬性和方法
三、原型繼承
當(dāng)我們通過new Person();
初始化一個(gè)實(shí)例的時(shí)候莱坎,實(shí)例一創(chuàng)造出來就具有constructor
屬性(指向構(gòu)造函數(shù))和_proto_
屬性(指向原型對象)
function Person(name){ //構(gòu)造函數(shù)
this.name=name;
}
let person1=new Person('name'); //實(shí)例化對象
console.log(person1._proto_== Person.prototype); // true
console.log(person1.constructor);//function Person(name){ this.name=name }
子對象可以繼承父對象的prototype
衣式,往上繼承直到object
,也就是null
詳解
-
prototype:
是每個(gè)函數(shù)都有的一個(gè)屬性檐什,包含給后代用的屬性方法 -
_proto_:
是實(shí)例對象的屬性碴卧,保存父類的prototype
實(shí)例的屬性:
-
constructor
(指向構(gòu)造函數(shù)) -
_proto_
(指向原型對象)
原型對象(構(gòu)造函數(shù).prototype) 的屬性:
-
構(gòu)造函數(shù).prototype.constructor == 實(shí)例對象.constructor
,都是構(gòu)造函數(shù) -
_proto_
指向父對象的原型對象
當(dāng)實(shí)例訪問原型鏈上的方法時(shí),他們的地址是共享的乃正,所以輸出兩個(gè)實(shí)例是相等的住册,如果是實(shí)例方法,不同的實(shí)例化瓮具,他們的方法地址是不一樣的
四荧飞、自有屬性和繼承屬性
Javascript對象擁有自有屬性和繼承屬性
- 自有屬性:如通過構(gòu)造函數(shù)
this.name=name
設(shè)置的屬性 - 繼承屬性:如
對象.prototype
的屬性
可以使用object.hasOwnProperty(proName)
來判斷對象的屬性是否是自有屬性,如果是則返回 true名党,否則返回 false叹阔,此方法不會(huì)檢查對象原型鏈中的屬性,因此可用來過濾繼承屬性
五传睹、屬性查找賦值
- 當(dāng)查找一個(gè)對象的屬性時(shí)耳幢,JS會(huì)向上遍歷原型鏈,直到找到該屬性欧啤,如果沒有找到睛藻,返回
undefined
- 當(dāng)給一個(gè)對象的屬性賦值時(shí),如果自有屬性中包含這個(gè)屬性則改變它的值邢隧,若不存在或繼承屬性中有這個(gè)屬性店印,都為對象創(chuàng)建這個(gè)屬性并賦值
也就是說,只有在查詢時(shí)原型鏈才會(huì)起作用府框,賦值只針對自有屬性
六吱窝、設(shè)置原型的方式
let Calculator = function () { };
- 方式一:分別設(shè)置原型對象
Calculator.prototype.add = function (x, y) {
return x + y;
};
Calculator.prototype.subtract = function (x, y) {
return x - y;
};
- 方式二:通過給對象的
prototype
屬性賦值來設(shè)定對象的原型
Calculator.prototype = {
add: function (x, y) {
return x + y;
},
subtract: function (x, y) {
return x - y;
}
};
alert((new Calculator()).add(1, 3));