Javascript中的类
我们上一章聊到的构造函数,从很多面向对象语言过来的开发者都不习惯称为构造函数,习惯称之为类(class),从编程范式来看,确实可以称之为类。
面向对象有三大特性:封装、继承、多态
封装:我们前面将属性和方法封装到一个类中,可以称之为封装的过程继承:继承是面向对象中非常重要的,不仅仅可以减少重复代码的数量,也是多态前提(纯面向对象中)多态:不同的对象在执行时表现出不同的形态 我们之前的构造函数的赋值过程就是封装,我们接下来要讲的重点是继承。在了解继承之前,我们要了解Javascript中的原型链(prototype chain)。
Javascript中的原型链
原型链(prototype chain)是由一个一个的原型对象不断向上攀升连接所形成的链条,但是这个链条实际上是虚拟的,只是形象地表示原型对象之间的关系。
const obj = {
name: 'zengge',
age: 22
}
console.log(obj.height)
我们此时打印obj.height,显然会提示undefined。这是因为我们obj本身并没有height这个属性,但是实际上js的查找机制并不是只在当前对象中查找,而是会沿着原型链查找,直到查找到原型链的顶端。如果我们在obj的原型对象__proto__上增加一个height属性,那么我们就可以查找并打印出来这个属性。
const obj = {
name: 'zengge',
age: 22
}
obj.__proto__ = {
height: 1.88
}
console.log(obj.height)
以此类推,我们只要在这条原型链上任意一个原型对象上设置了height属性,那么都可以被查找并打印出来。
const obj = {
name: 'zengge',
age: 22
}
obj.__proto__.__proto__.__proto__ = {
height: 1.88
}
console.log(obj.height)
Javascript中的继承
我们现在有两个构造函数Teacher, Student分别有各自的方法和属性,但是也有共同的方法和属性,代码如下:
function Teacher(name, age, title) {
this.name = name
this.age = age
this.title = title
}
Teacher.prototype.sayHello = function() {
console.log(`你好我是${this.name}`)
}
Teacher.prototype.teach = function() {
console.log(`${this.name}teaching`)
}
function Student(name, age, course) {
this.name = name
this.age = age
this.course = course
}
Student.prototype.sayHello = function() {
console.log(`你好我是${this.name}`)
}
Student.prototype.studying = function() {
console.log(`${this.name}studying`)
}
其中name,age是公共属性,sayHello是公共方法,title,course是私有属性,teach,studying是私有方法。这样会造成代码冗余,所以我们需要一个公共的类来继承他们的公共部分。这样就需要用到Javascript中的继承。
function Person() {
}
Person.prototype.sayHello = function() {
console.log(`你好我是${this.name}`)
}
function Teacher(title) {
this.title = title
}
Teacher.prototype = new Person()
Teacher.prototype.teach = function() {
console.log(`${this.name}teaching`)
}
function Student(course) {
this.course = course
}
Student.prototype = new Person()
Student.prototype.studying = function() {
console.log(`${this.name}studying`)
}
const teacher = new Teacher('Math')
const student = new Student('Math')
stu.sayHello()
teacher.sayHello()
我们创建了一个Person构造函数,将Person放到了Teacher和Student的原型链上,这样就充当了父类,可以访问父类上公共的属性或者方法。