在平時開發時,我們會遇到要創建許多類型相似的object,之前的文章有提到使用new操作符配合function可以達到我們的需求,而今天要介紹的是Class。
calss ownClass {
constructor() {}
method1() {}
method2() {}
method3() {}
}
實際舉個例子說明new class的一些觀念:
class Cat {
constructor(name) {
this.name = name
}
jump() {
console.log(`${this.name} jump!`)
}
eat() {
console.log(`${this.name} eat!`)
}
}
let catA = new Cat("CatA");
console.log(typeof Cat); // function
console.log(Cat === Cat.prototype.constructor) // true
console.log(Cat.prototype.jump) // console.log(`${this.name} jump!`)
console.log(Object.getOwnPropertyNames(Cat.prototype)) // ["constructor", "jump", "eat"]
許多文章都認為class只是語法糖,可以用一般的構造器重複寫出相同於上面Cat的功能:
function Cat(name) {
this.name = name
}
Cat.prototype.jump = function() {
console.log(`${this.name} jump!`)
}
Cat.prototype.eat = function() {
console.log(`${this.name} eat!`)
}
let catA = new Cat("CatA");
構造器與Class差別:
與函數一樣有聲明與表達式兩種,上面介紹的是聲明式,以下是表達式的例子:
let Cat = class {
jump() {
console.log(`${this.name} jump!`)
}
}
類似於函數的具名表達式,Class也有,不過只在函數內可見:
let Cat = class CatClass {
jump() {
console.log(`${this.name} jump!`)
}
getClassName() {
console.log(CatClass)
}
}
let catA = new Cat;
catA.getClassName(); class CatClass{...}
console.log(CatClass); // CatClass is not defined
class Cat {
constructor(name) {
this.name = name
}
get name() {
return this._name
}
set name(value) {
this._name = value
}
}
let catA = new Cat("catA");
console.log(catA.name); // catA
catA.name = 'catB';
console.log(catA.name) // catB
在Class中新增的屬性會獨立的在每個object中新增,而不是新增在prototype中。
class Cat {
name = "catA";
jump() {
console.log(`${this.name} jump!`)
}
}
new Cat().jump(); // catA jump!
新增屬性也可以作為Day11函數綁定的一個解法:
class Cat {
constructor(name) {
this.name = name
}
jump() {
console.log(`${this.name} jump!`)
}
}
let catA = new Cat("catA");
setTimeout(catA.jump,1000) // undefined
可以運用箭頭函數的特性,this會指向父作用域的this,在下面的例子中就會指向Cat這個function的this,也就會指向catA。
class Cat {
constructor(name) {
this.name = name
}
jump = () => {
console.log(`${this.name} jump!`)
}
}
let catA = new Cat("catA");
setTimeout(catA.jump,1000) // catA jump!