Class & 继承 & 原型 & 原型链


整个七月到八月真是一堆事情,现在终于有空了,静下心复习一段时间刷刷面试题,准备去面试找工作了,希望在国庆之前能找到合适的工作,加油。

Class

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

类的声明

比如 声明一个类,并声明一个该类的实例

class Student {
    //constructor 构造函数
    constructor(name, number){
        //创建实例的时候 这里this指向当前创建的实例
        this.name = name 
        this.number = number
        this.gender = 'male'
    }
    sayHi() {
        console.log(`${this.name} + ${this.number}`)
    }
}

// 通过类 声明对象/实例
const gary = new Student('盖瑞',101)
console.log(gary.name)
console.log(gary.number)
console.log(gary.gender)
gary.sayHi()

继承

Class可以通过extends关键字实现继承;这比ES5的通过修改原型链实现继承,要清晰和方便很多。

//继承
//定义一个父类
class People {
    constructor(name) {
        this.name = name
    }
    eat() {
        console.log(`${this.name} eat`)
    }
}

//子类一
class Student extends People {
    constructor(name, number) {
        //通过子类的super函数 把属性传递给父类的constructor函数进行处理
        super(name)
        this.number = number
    }
    sayHi() {
        console.log(`${this.name} + ${this.number}`)
    }
}
//子类二
class Teacher extends People{
    constructor(name, major) {
        super(name)
        this.major = major
    }
    teach() {
        console.log(`${this.name} teach ${this.major}`)
    }
}

const gary = new Student('盖瑞', 101)
console.log(gary.name)
console.log(gary.number)
gary.sayHi()
gary.eat()

const laowang = new Teacher('老王','计算机')
console.log(laowang.name)
console.log(laowang.major)
laowang.teach()
laowang.eat()

instanceof 类型判断

可以通过instanceof 来判断实例属于哪个类

console.log(gary instanceof Student) //true
console.log(gary instanceof People) //true
console.log(gary instanceof Object) //true Object相当于顶级

console.log([] instanceof Array) //true
console.log([] instanceof Object) //true

console.log({} instanceof Object) //true

原型 & 原型链

// class 实际上是函数,是语法糖
console.log(typeof People) //'function'
console.log(typeof Student) //'function'

// 隐式原型 - 显示原型
console.log(gary.__proto__)
console.log(Student.prototype)
console.log(gary.__proto__ === Student.prototype) //true

所以,简单来说可以这样理解:
1.每个class都有显示原型prototype。
2.每个实例都有隐式原型__proto__。
3.实例的__proto__ 指向对应class的prototype。

那么,原型的规则:
获取属性gary.name 或者 执行方法 gary.sayHi()时,
先在自身属性和方法里寻找,找到了直接获取或执行。
如果没有,就自动在__proto__中去查找。

那么类Student是继承于类People的,所以

console.log(Student.prototype.__proto__)
console.log(People.prototype)
console.log(People.prototype === Student.prototype.__proto__) //true

所以当在自身属性跟方法中找不到的时候,就会顺着__proto__一级级往上寻找
于是,当你输出gary.hasOwnProperty(‘sayHi’)时,输出为false。
这也就是深拷贝中为什么在递归里面要先用hasOwnProperty来判断一下拷贝的属性或者方法是不是拷贝对象自身的。

Object作为顶级对象,就没有隐式原型了,所以可以说Object.prototype就是原型链的顶端,原型链到此结束。

Object.prototype.__proto__ //null

class是ES6的一个语法规范,由ECMA委员会发布的,委员会只规定语法规则,不管实现,所以以上的实现方式都是浏览器的V8引擎的实现方式,这也是主流。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值