ES5中构造函数
在ES5中没有类的概念,但是我们可以通过构造函数来实现类
function Parent(name, sex) {
this.name = name
// 实例属性
this.sex = sex
// 实例方法
this.run = function() {
console.log('runing')
}
}
// 静态属性
Parent.prop = 'hello'
// 静态方法
Parent.classMethod = function() {
console.log('我是静态方法')
}
// 原型方法
Parent.prototype.speek = function() {
console.log('speeking')
}
const parent = new Person('tony', '男')
ES6中Class
ES6中的Class可以看作是一个语法糖(底层还是通过构造函数去创建的),它的绝大部分功能,ES5都可以实现,新的Class的写法只是让对象原型的写法更加清晰,更像面向对象编程的写法。
class Parent {
// 静态属性,不能被实例对象继承,只能通过class直接调用
static staticProp = 'hello world'
constructor(name, sex) {
this.name = name
// 实例属性
this.sex = sex
// 实例方法
this.run = function() {
console.log('runing')
}
}
// 静态方法,不会被实例继承,但可以被子类继承
static classMethod() {
console.log('我是静态方法')
}
// 原型方法,会被实例继承
speek() {
console.log('speek')
}
// 原型方法
sleep() {
return 'sleeping'
}
}
// 子类Sun继承父类Parent
class Sun extend Parent {
constructor(name, sex, age) {
// 通过super调用父类的constructor函数,将父类的实例对象和属性添加到子类的this上,实现继承
// 子类自己的this对象,必须先通过调用父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后对其进行加工,加上自己的实例属性和方法,如果不调用super方法,子类就得不到this对象
super(name, sex)
this.age = age
}
sleep() {
return this.name + super.sleep() // 调用父类原型对象的sleep()
}
}
const parent = new Parent('tony', '男')
const sun = new Sun('tim', '男', '10')
-
class中constructor是内部默认的方法,如果没有声明则会被默认添加和调用,通过new关键字操作实际是调用constructor方法, 返回实例对象(即this)
-
class中内部可以通过static关键字定义静态属性和方法,直接通过类来调用,实例对象不能调用
-
子类的this对象是通过super()调用父类的constructor构造函数来实现的, 在调用super之前不能使用this进行赋值操作,赋值会报错
super调用
super作为函数调用
子类B的构造函数中的super,指向父类的构造函数constructor
class A {}
class B extend A {
constructor() {
super()
}
}
要注意的是:super虽然代表了父类的构造函数,但是返回的是子类B的实例,即super内部的this指的是B的实例
super作为对象调用
在普通方法中:指向父类的原型对象
在静态方法中:指向父类
两者区别
-
ES5声明的构造函数有变量提升,ES6声明的class类没有提升(这种规定的原因与继承有关,必须保证子类在父类之后定义)
-
ES5中通过prototype原型添加的方法是可以被枚举的,而ES6中在class内部添加的原型方法是不可被枚举的