bp[ 原型最重要的是为了share(共享), 共享一些方法和属性。
原型Prototype
JavaScript 是一门基于原型的语言,每个对象都有一个原型(对象)作为模板。
通过原型这种机制,对象能从其他对象继承功能特性;这种继承机制与经典的面向对象编程语言不同。
__proto__
每一个对象都有一个__proto__属性用于继承功能特效,该属性不是标准的一部分,但却是事实标准
。
声明对象 fan 如下, 当访问name,traval()等自身具有的属性/方法时,会从对象自身获取;
当访问,valueOf(), toString(),等非自身属性/方法时,会从(也只能)__proto__属性上获取。
let fan = {
name:'女粉丝',
gender:'女',
height:162,
eat(){ return `吃饭。`},
sleep(){return `睡觉`},
intro() {return `大家好!我是${this.name}。`},
travel() {return'环游世界 🌏🌎🌍'}
}
>fan.name
→"吕粉丝"
>fan.travel()
→"环游世界 🌏🌎🌍"
>fan.valueOf()
→Object{name:"吕粉丝", height:162, gender:"女",eat:function,sleep:function…}
Object.prototype
以下代码都描述了 一个事实, 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 方法允许使用指定的原型对象和属性,创建一个新的属性
//常人的属性和方法//常人的原型
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'环游世界 🌏🌎🌍'}
显然,以下表达式都会返回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'环游世界 🌏🌎🌍'}
eat functioneat() {return'吃饭 🍚'}
sleep functionsleep() {return'睡觉 😴'}
sing functionsing() {return'唱歌 🎤'}
intro functionintro() {return`大家好!我是${this.name}。`}
→undefined
由于for...in会把继承的属性和方法都进行遍历,因此需要Object.prototype.hasOwnProperty()。
>for(letkeyinfan)fan.hasOwnProperty(key)&&console.log(key, fan[key])
name 吕粉丝
height 162
gender 女
travel function() {return'环游世界 🌏🌎🌍'}
→false
原型链 Prototype Chiin
原型本身就是一个对象,因此也有__proto__属性。即原型的原型。还有原型的原型的原型等。这就是原型链。
Object.prototype.__proto__的值是null,而null 没有原型,到此就是原型链末端。
//创建艺人的原型
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}。其实我是一个演员。`}
kris['有 freestyle 吗?']=function() {return['有 freestyle 吗?','还有 freestyle 吗?','有没有 freestyle?'][Math.floor(Math.random()*3)]};
以下代码中jay.intro()和kris.intro()的intro()方法分别来自哪里?
在对象创建之后往其原型新增属性/方法,对象可以立即访问到。
>jay.sing()
→"唱歌 🎤🎧🎸"
>artistProto.film=function() {return'拍戏 🎬🎬🎬'}
→function() {return'拍戏 🎬🎬🎬'}
>jay.film()
→"拍戏 🎬🎬🎬"
instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的prototype 属性。
var a = [1,2,3]
a instanceof Object // 意思是 a 的原型链上有没有Object.prototype
truea.constructor
function Array([native code])
a.__proto__ === a.constructor.prototype // a.constructor. prototype === Array.prototype
true