書籍地址: ECMAScript 6 入門
class在es6中就是一個語法糖,只是與es5定義類時候的寫法不一樣,功能還是一樣的
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayAge() {
console.log(this.age);
}
}
Person.prototype.sayName = function () {
console.log(this.name);
};
裏面的name
和age
屬性在Person
上,sayAge
和sayName
方法在Person.prototype
上
this的使用
使用class
定義的類的內部有this
,他將默認指向類的實例
使用其他的方式定義一個類,並將裏面的方法取出來可以單獨使用
var myName = 'Windows name';
let obj = {
myName: "obj name",
say: function () {
console.log(this.myName);
}
};
obj.say();
//使用賦值解構的方式取出say
let { say } = obj;
say();
但是使用class
定義的類,將裏面的方法取出來無法單獨使用
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
console.log(this);
console.log(this.name);
}
}
var name = "Windows name";
let person = new Person('hzj', 19);
let { sayName } = person;
sayName();
調用sayName方法的時候,發現this
是undefined
,所以無法使用this.name
解決方法
- 最簡單的方法: 使用bind綁定this
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
this.sayName = this.sayName.bind(this);
}
sayName() {
console.log(this);
console.log(this.name);
}
}
set和get使用
定義的set
和get
方法會改變某個屬性的存值行爲和取值行爲
class Person {
constructor(name, age) {
this._name = name;
this.age = age;
}
get name() {
console.log('調用了get name方法');
return this._name;
}
set name(name) {
console.log('調用了set name方法');
this._name = name;
}
}
let person = new Person("hzj", 22);
person.name = 'xm';
console.log(person.name);
console.log(person._name);
_name
並不是私有的,可以直接取值和設置值,只是在命名上進行區別
靜態方法
使用static
定義的方法不能在類的實例對象上使用,可以通過類.方法名()
使用
static
定義的方法可以被子類繼承,可以通過子類名.方法名()
調用或者通過supper().方法名()
調用
class Foo {
constructor(name, age) {
}
static hello() {
console.log('hello world');
}
}
let foo = new Foo();
Foo.hello();
class Child extends Foo {
static useHello() {
super.hello();
}
}
Child.hello();
Child.useHello();
即使是子類的實例對象,也不能夠使用父類的靜態方法
class Child extends Foo {
useHello() {
super.hello();
}
}
let child = new Child();
child.useHello(); //TypeError: (intermediate value).hello is not a function
new.target
用來判斷是否使用new
關鍵字創建的對象
- 限制對象必須通過
new
使用
function Person(name, age) {
if (new.target === undefined) {
throw new Error('必須使用new關鍵字使用');
} else {
this.name = name;
this.age = age;
}
}
Person('hzj', 22);
let person = new Person('hzj', 22);
- 在
class
中可以限定必須通過子類進行實例化,本身不能實例化
class Person {
constructor(name, age) {
if (new.target === Person) {
throw new Error('必須使用new關鍵字生成實例');
} else {
this.name = name;
this.age = age;
}
}
}
class Child extends Person {
constructor(name, age, classes) {
super(name, age);
this.classes = classes;
}
}
let child = new Child('hzj', 22, 1);
let person = new Person('hzj', 22); //Error: 必須使用new關鍵字生成實例
suppr
必須在this
的前面使用
這是錯誤的使用方式
constructor(name, age, classes) {
this.classes = classes;
super(name, age);
}