原型及原型链

写在前面: 这篇文章主要是根据自己的理解分享了什么是原型和原型链

  1. 原型, 原型链, 原型对象, 实例, 的定义
  2. 原型对象图示
  3. 如何获取原型对象

原型, 原型链, 原型对象的定义

1. 什么是实例,如何创建实例

实例就是通过 构造函数 / 或者其他方法 生成的一个对象
例如:

//1- 通过字面量方式实例化对象
let a = {
	name: '张三'
}

//2- 通过 new Object 来实例化一个对象 b就是一个实例
let b = new Object()//b = {}

//3- 通过构造函数来实例化一个对象 p也是一个实例
function Person (name) {
	this.name = name
}
let p = new Person('张三') 

当我们打印这些实例的时候,会发现有一个 __ proto __ (双下划线)的属性,它的类型是一个对象(引用类型),b.__ proto __里面就存放着这个实例的原型对象
在这里插入图片描述
在解释其他内容之前,先抛出一个小例子来说明这些内容

//首先我写了一个人的构造函数(Person) 
function Person(name){
	this.name = name
}
//从上面可以知道 可以通过 new Person 来实例化一个对象
let p1 = new Person('张三')
//根据下面图1 打印p1 可以看出有一个 Person 的对象
//有一个属性叫做 name ,值为 '张三'
//它的原型对象(我给他取一个名字叫做 原型对象1)里面有一个 构造器 function Person(name)
//它的原型对象里面还有一个原型对象 (我给他取一个名字叫做 原型对象2)


图1 打印p1
在这里插入图片描述

2. 什么是原型对象

原型对象是由构造函数的prototype属性和这个构造函数创建的实例对象的__proto__属性共同指向的一个原型链上的对象

原型对象也是一个对象, 所以它也会有自己的原型对象(除非这个已经是顶层对象 Object 了===>Object 没有原型对象(指向 null))
如上图: p1.__ proto __ 指向的就是原型对象

3. 原型链

原型链是原型以及它的原型对象构成的链条 如上图 的原型链就是:
p1 -> 原型对象1 ->原型对象2
这个链条就叫做原型链

原型链图示

在这里插入图片描述

如何获取原型对象

通过实例化后的对象: p1.__ proto __
通过构造器: Person.prototype

给原型对象添加属性会怎样?
//分别用这两种方法给原型对象添加属性
p1.__ proto __.age = 18
Person.prototype.sex = '男'
console.log('p1.age',p1.age)//18
console.log('p1.sex',p1.sex)//男

添加后重新打印 person
在这里插入图片描述
在相关属性(方法)时,首先去找自身的属性和方法, 若没有找到, 就去找上层的原型对象里面的属性和方法(如下个例子,为最顶层的原型对象添加一个 desc 属性), 若逐层向上直到最顶层都还没有找到的话则不存在该属性或者方法(如果是打印: 则为 undefined )

Object.prototype.desc = 'object 的原型对象'
console.log(p1.desc) //打印结果 object 的原型对象
console.log(p1.c) //打印结果 undefined (在原型链中并不存在这个属性)
给原型对象赋值会怎么样?
//给顶层的 Object 的原型对象添加属性 
Object.prototype.sex = 'object 的原型对象的sex'
//若此时想要得到 p1.sex 
console.log(p1.sex) //打印结果 男 =====就近原则
//给 p1 的原型对象赋值(空对象)
p1.__proto__ = {}
console.log(p1.sex) //打印结果  object的原型对象的sex,因为 p1 的直接原型对象已经找不到了 sex 了
给原型对象赋一个不是对象的值会怎样?

我最先的想法是,如果原型对象已经不是一个对象了的话,这个原型链还会存在吗?
于是 修改代码

p1.__proto__ = 1
console.log(p1.name)//打印结果  张三
console.log(p1.age)//打印结果  undefined
console.log(p1.sex)//打印结果  object 的原型对象的sex(这个是在 p1 直接原型对象上的)
console.log(p1.desc)//打印结果  object 的原型对象

所以,总结一下,原型链并不会断裂,只会往顶层找,找不到就 undefined

//分享的所有代码
console.log('------------构造函数-----------------')
function Person(name) {
	this.name = name
}
let p1 = new Person('张三')
console.log(p1)
console.log('-----------给 p1 的原型对象添加属性------------------')
p1.__proto__.age = 18
Person.prototype.sex = '男'
console.log(p1)
console.log('p1.age',p1.age)//打印结果   18
console.log('p1.sex',p1.sex)//打印结果    男


console.log('-----------给顶层(Object)的原型对象添加属性------------------')
Object.prototype.desc = 'object 的原型对象'
Object.prototype.sex = 'object 的原型对象的sex'
console.log(p1.desc)//打印结果   object 的原型对象


console.log('-----------给 p1 的原型对象赋值(空对象)------------------')
p1.__proto__ = {}
console.log(p1.sex)//打印结果 object 的原型对象的sex


console.log('-------------给 p1 的原型对象赋值(非对象)----------------')
p1.__proto__ = 1
console.log(p1.name)//张三
console.log(p1.age)//undefined
console.log(p1.sex)//object 的原型对象的sex
console.log(p1.desc)//object 的原型对象

end
参考资源:回顾——原型对象、原型链、构造函数、实例对象之间的关系

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值