JS中的原型和原型链

构造函数、实例、原型三者的关系

在JavaScript中每创建一个函数,就会为这个函数创建一个prototype属性,该属性指向函数的原型对象,而这个原型对象在默认情况下会有一个名为constructor的属性指回构造函数。

//定义构造函数
function Person(){
}
//拿到Person的原型对象
let pro=Person.prototype

//给原型添加属性
pro.name="Kobe"
pro.age=16

//验证Person的原型对象的constructor属性是否指回Person
console.log(pro.constructor===Person)		//	true

通过构造函数来创建实例,该实例内部的__ proto__属性也会指向构造函数的原型对象

let p1=new Person()
let p2=new Person()
console.log(p1.__proto__===Person.prototype)		//	true
console.log(p2.__proto__===Person.prototype)		//	true

看图说话:
请添加图片描述

通过实例来修改原型上的属性

  • 如果修改的是保存引用值的属性上的一个或多个属性,则会修改原型上的属性
//定义构造函数
function Person() {
    Person.prototype.msg = {
        name: '张三',
        age: 18
    }
    Person.prototype.color=['yellow','blue']
}

let p=new Person()
p.msg.name="李四"
p.msg.age=30
console.log(Person.prototype.msg)		//	{name: "李四", age: 30}
p.color.push('black')
console.log(Person.prototype.color)		//	['yellow','blue','black']
  • 如果修改的是保存原始值的属性,或直接将保存引用值的属性“整个儿换掉”,则不会修改原型上的属性,而是直接在实例对象上添加我们修改的属性
//定义构造函数
function Person() {
    Person.prototype.name = "Kobe"
    Person.prototype.job = {
        salary: '30k'
    }
}
let p = new Person()
p.name = "Alice"
p.job = {
    str:'hello'
}
console.log(p)
console.log(p.__proto__)

打印结果:

请添加图片描述

请添加图片描述

很明显,对于这种情况只会把要“修改的属性”添加到自身

原型链

每个构造函数都有一个原型对象,原型有一个属性指回构造函数,而实例有一个内部指针指向原型。如果原型是另一个类型的实例呢?那就意味着这个原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链。这就是原型链的基本构想 ——《JavaScript高级程序设计第四版》

原型解决了数据共享问题,即多个实例共享原型上的数据。那么如果不同的构造函数所创建的实例要想共享数据呢?原型链就可以解决这个问题。

做个假设:A实例要想要想从毫不相干的B实例身上取数据。

如果想要实现这种效果,我们可以把A类型的prototype属性指向B类型的实例,即重写A的原型对象为B实例对象,这样就实现了一种继承关系。如果想要通过A实例查找某一属性,会先从自身找,找不到会从原型对象(B实例)上找,找不到继续在原型对象的原型对象(B实例的原型对象)上找…这个查找过程就是在原型链上查找的。

function A() {}

function B() {
    B.prototype.num = 12
}
//重写A类型的原型
A.prototype = new B()

//创建A实例
let a = new A()

console.log(a.num)      //  12

默认原型

任何一个函数的原型默认都是一个Object类型的实例,所以原型的__ proto__会指向 Object.prototype(即Object构造函数的原型),Object的原型的原型为null,即原型链的尽头。

function Cf() {}
let c = new Cf()
    //这里c是Cf类型的实例,而c的原型默认是Object类型的实例
console.log(c.__proto__ instanceof Object) //true
console.log(c.__proto__.__proto__ === Object.prototype) //true
console.log(Object.prototype.__proto__) //null
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值