Prototype

作者: 饥人谷_Chou | 来源:发表于2017-10-25 19:57 被阅读0次

 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
true 

a.constructor
function Array([native code])
a.__proto__ === a.constructor.prototype  // a.constructor. prototype  === Array.prototype
true

相关文章

网友评论

      本文标题:Prototype

      本文链接:https://www.haomeiwen.com/subject/dzipuxtx.html