?bp[ 原型最重要的是為了share(共享), 共享一些方法和屬性琳轿。
原型Prototype
JavaScript 是一門基于原型的語言,每個對象都有一個原型(對象)作為模板挪哄。
通過原型這種機(jī)制迹炼,對象能從其他對象繼承功能特性;這種繼承機(jī)制與經(jīng)典的面向?qū)ο缶幊陶Z言不同砂碉。
__proto__
每一個對象都有一個__proto__屬性用于繼承功能特效增蹭,該屬性不是標(biāo)準(zhǔn)的一部分磅摹,但卻是事實(shí)標(biāo)準(zhǔn)
。
聲明對象 fan 如下饼灿, 當(dāng)訪問name帝美,traval()等自身具有的屬性/方法時悼潭,會從對象自身獲取;
當(dāng)訪問漆枚,valueOf(), toString(),等非自身屬性/方法時抵知,會從(也只能)__proto__屬性上獲取。
let fan = {
name:'女粉絲',
gender:'女',
height:162,
eat(){ return `吃飯残制。`},
sleep(){return `睡覺`},
intro() {return `大家好掖疮!我是${this.name}。`},
travel() {return'環(huán)游世界 ??????'}
}
>fan.name
→"呂粉絲"
>fan.travel()
→"環(huán)游世界 ??????"
>fan.valueOf()
→Object{name:"呂粉絲", height:162, gender:"女",eat:function,sleep:function…}
Object.prototype
以下代碼都描述了 一個事實(shí)恼布, Object,prototype (引用的對象) 是fan 的原型折汞。
>fan.__proto__===Object.prototype//fan.__proto__ 和 Object.prototype 引用同一對象
→true
>Object.prototype.isPrototypeOf(fan)//Object.prototype(引用的對象) 是 fan 的原型
→true
>Object.prototype===Object.getPrototypeOf(fan)
→true
Object.create()
Object.create() ES5 ?方法允許使用指定的原型對象和屬性爽待,創(chuàng)建一個新的屬性
//常人的屬性和方法//常人的原型
const personProto? = {
name:' ',
eat() {return'吃飯 ??'},
sleep() {return'睡覺 ??'},
sing() {return'唱歌 ??'},
intro() {return`大家好!我是${this.name}膏燃。`}
}//讓 personProto 作為 fan 的原型
let fan= Object.create(personProto)
fan.name='呂粉絲'
fan.height=162
fan.gender='女'
fan.travel=function() {return'環(huán)游世界 ??????'}
顯然组哩,以下表達(dá)式都會返回true富俄。
fan.__proto__ === personProto
true
personProto.isprototype(fan)
true
personProto === Object.getPrototypeOf(fan)true
通過Object.keys()獲取fan的所有屬性名。
>Object.keys(fan)
→ ["name","height","gender","travel"]
Object.prototype.hasOwnProperty()
Object.prototype.hasOwnProperty()方法是用于判定某個指定的屬性是否對象的自身(非繼承)屬性。
>for(letkeyinfan)console.log(key, fan[key])?
name 呂粉絲?
height162
gender 女?
travel? function() {return'環(huán)游世界 ??????'}?
eat? functioneat() {return'吃飯 ??'}?
sleep? functionsleep() {return'睡覺 ??'}?
sing? functionsing() {return'唱歌 ??'}?
intro? functionintro() {return`大家好悠瞬!我是${this.name}涯捻。`}
→undefined
由于for...in會把繼承的屬性和方法都進(jìn)行遍歷障癌,因此需要Object.prototype.hasOwnProperty()。
>for(letkeyinfan)fan.hasOwnProperty(key)&&console.log(key, fan[key])?
name 呂粉絲?
height 162
gender 女?
travel? function() {return'環(huán)游世界 ??????'}
→false
原型鏈 Prototype Chiin
原型本身就是一個對象康辑,因此也有__proto__屬性疮薇。即原型的原型我注。還有原型的原型的原型等。這就是原型鏈励七。
Object.prototype.__proto__的值是null,而null 沒有原型,到此就是原型鏈末端补履。
//創(chuàng)建藝人的原型
const? artistProto=Object.create(personProto)
artistProto.sing=function() {return '唱歌 11??????'}//讓 artistProto 作為 jay 的原型
let? jay=Object.create(artistProto)
jay.name='周杰倫'
jay.height=175
jay.gender='男'
jay.aiyo=function() {return'哎喲箫锤,不錯哦雨女!'}
//讓 artistProto 作為 kris 的原型
let kris=Object.create(artistProto)
kris.name='吳亦凡'
kris.height=187
kris.intro=function() {return`歌手${this.name}。其實(shí)我是一個演員馏臭。`}
kris['有 freestyle 嗎括儒?']=function() {return['有 freestyle 嗎?','還有 freestyle 嗎帮寻?','有沒有 freestyle固逗?'][Math.floor(Math.random()*3)]};
以下代碼中jay.intro()和kris.intro()的intro()方法分別來自哪里藕帜?
在對象創(chuàng)建之后往其原型新增屬性/方法于樟,對象可以立即訪問到笆凌。
>jay.sing()
→"唱歌 ??????"
>artistProto.film=function() {return'拍戲 ??????'}
→function() {return'拍戲 ??????'}
>jay.film()
→"拍戲 ??????"
instanceof? 運(yùn)算符用來測試一個對象在其原型鏈中是否存在一個構(gòu)造函數(shù)的prototype 屬性隘弊。
var a = [1,2,3]
a instanceof Object? ?//? 意思是 a 的原型鏈上有沒有Object.prototype
true?a.constructor
function Array([native code])
a.__proto__ === a.constructor.prototype? //?a.constructor. prototype??=== Array.prototype
true