JavaScript的原型和原型链

JavaScript的原型和原型链

原型和原型链是JavaScript的非常重要的知识点,下面分享下我对它的理解。

class和继承

在ES6,js引入了class关键字,用来声明一个类,我们可以使用constructor来构建对象,包括我们需要的属性和方法。但是它的底层实现依然是原型和原型链,继承也是基于原型链的链式继承。
下面看一下如何使用class声明一个类,并且实例化一个对象:

class People {
    constructor (name) {
        this.name = name
    }
    sayHi() {
        console.log(`你好,我是${this.name}`)
    }
}
// 实例化并使用
const p = new People('一个人')
p.sayHi() // 结果: 你好,我是一个人

上面我们声明了一个类,并实例化使用了它;接下来,我再声明两个类使用extends关键字分别继承People类

class People {
    constructor (name) {
        this.name = name
    }
    sayHi() {
        console.log(`你好,我是${this.name}`)
    }

}

class Student extends People {
    constructor (name,number) {
        super(name)
        this.number = number
    }
    learn() {
        console.log(`我是${this.name},学号是${this.number},我在学习`)
    }
}

class Teacher extends People{
    constructor (name, age) {
        super(name)
        this.age = age
    }

    sayHi() {
        console.log(`你好,我是一名教师,我重写了父类的这个方法`)
    }

    teach() {
        console.log(`我是${this.name},年龄是${this.age},我在教学`)
    }
}


const xiaoming = new Student('小明', 1001)
const teacher1 = new Teacher('teacher1', 35)
xiaoming.learn() // 结果: 我是小明,学号是1001,我在学习
teacher1.teach() // 结果: 我是teacher1,年龄是35,我在教学
xiaoming.sayHi() // 结果: 你好,我是小明
teacher1.sayHi() // 结果: 你好,我是一名教师,我重写了父类的这个方法

上面一段代码,我们声明了Student 和Teacher类分别继承People,在构造函数中,可以使用super关键字同样的他也是父类的构造方法,使用它,我们可以初始化继承自父类的属性,并且可以使用super.父类方法的方式调用父类的方法。并且我们可以在子类中重写类型的函数如上述代码在teacher中重写了sayHi()。

原型

在弄清楚了class和继承之后,我们再来看一下原型。下面在以上代码的基础上再来看一段代码

console.log(xiaoming.__proto__)
console.log(Student.prototype)
console.log(xiaoming.__proto__ === Student.prototype) // 结果: true

在这里插入图片描述
根据以上结果,我们发现xiaoming.__proto__和Student.prototype是一样的那么它们的关系就如下图所示,在Student中会有一个prototype指向一个对象,而在实例化一个xiaoming对象的时候会产生一个__proto__属性也指向这个对象。
在这里插入图片描述

同样的根据这个图可以总结出原型关系就是:(1)每个对象上面都有一个隐式原型__proto__;(2)每个类上面也都有一个显示原型prototype;(3)对象的__proto__都指向对应类的prototype。基于这种关系,在使用对象的属性方法时,会先在自身属性和方法中寻找,如果找不到则去隐式原型__proto__中找。

原型链

下面我们在原型关系的基础上继续分析原型链到底是一个怎样的链。首先我们看下面的结果
在这里插入图片描述
它为什么会是这样的结果呢?下面通过一张图片来理解下。
在这里插入图片描述
由于Student类是继承于People类所以Student.prototype的隐式原型__proto__指向的是People的显示原型prototype,同理最终指向了Object的prototype,这就是原型链。

hasOwnProperty()和instanceof关键字

hasOwnProperty方法是Object上的方法,它能够判断对象的某个属性是自己的并不是链上其它类的属性。
instanceof关键字用来判断对象或者类是否属于某个类,它的原理就是顺着原型链一层层往上找,只要能在A的原型上找到B的的显示原型,instanceof的结果就是true。

// xiaoming.__proto__ === Student.prototype
console.log(xiaoming instanceof Student) // 结果: true
// xiaoming.__proto__.__proto__ === People.prototype
console.log(xiaoming instanceof People) // 结果: true
// xiaoming.__proto__.__proto__.__proto__ === People.prototype
console.log(xiaoming instanceof Object) // 结果: true
// xiaoming的在原型链上找不到Teacher的显示原型
console.log(xiaoming instanceof Teacher) // 结果: false
// People.prototype.__proto__=== Object.prototype
console.log(People instanceof Object) // 结果: true

以上就是我对原型和原型链的理解,如有不足,请多多指教。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值