一.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.繼承關係
還是原型鏈繼承