一.Class
1.概念和语法
是函数链式继承的语法糖,大部分功能都是一样的,有少数不同
(1)constructor有且只有一个,不声明则js引擎会自动添加一个空的constructor
(2)类方法内部的this指向当前实例,当类的方法独立抽离出来的时候,this会指向方法的上下文环境,从未出错. 因此应该用实例调用实例方法
class Logger {
printName(name = 'there') {
this.print(`Hello ${name}`);
}
print(text) {
console.log(text);
}
}
const logger = new Logger();
// 最好不要独立使用类方法
const { printName } = logger;
printName(); // TypeError: Cannot read property 'print' of undefined
// 用实例调用类方法
logger.printName (); // Hello there
(3)Class的静态属性和静态方法
即定义在Class本身上的,而不是在Class实例上的静态属性和静态方法,静态方法前加static关键字
// 定义静态属性
class Foo {
}
// 正确
Foo.prop = 1;
Foo.prop // 1
// 以下两种写法都无效
class Foo {
// 写法一
prop: 2
// 写法二
static prop: 2
}
Foo.prop // undefined
// 定义静态方法
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function
(4)new.target
- 一般用在构造函数中,返回new命令作用于哪个构造函数,若不是通过new调用的,就会返回undefined
- 在函数内调用返回Class名字
- 子类继承父类后,父类中new.target会返回子类类名
function Person(name) {
if (new.target !== undefined) {
this.name = name;
} else {
throw new Error('必须使用 new 命令生成实例');
}
}
// 另一种写法
function Person(name) {
if (new.target === Person) {
this.name = name;
} else {
throw new Error('必须使用 new 命令生成实例');
}
}
var person = new Person('张三'); // 正确
var notAPerson = Person.call(person, '张三'); // 报错
二.Class继承
es6使用extends实现继承
继承原理:
先创建父类的实例对象this,然后子类的构造函数修改父类对象的this(因此要在子类构造函数内先调用super()以获取this),实现继承.
这不同于es5的直接修改原型链继承方式,es5是先创建子类的实例对象,然后将父类的方法添加到子类this上
1.继承关系
还是原型链继承