ES5 中怎麼聲明一個類?ES6 如何實現?
ECMAScript 2015 中引入的 JavaScript 類實質上是 JavaScript 現有的基於原型的繼承的語法糖。類語法不會爲JavaScript引入新的面向對象的繼承模型。
// ES5 類的定義和實例化
let Animal = function (type) {
this.type = type
}
Animal.prototype.eat = function () {
console.log('I am eat food')
}
let dog = new Animal('dog')
let monkey = new Animal('monkey')
console.log(dog)
console.log(monkey)
monkey.constructor.prototype.eat = function () {
console.log('eat')
}
dog.eat()
monkey.eat()
// ES5 聲明類時,共有的元素放在原型鏈 prototype 上,構造函數內實例對象可以單獨定義的放在構造函數體內,通用的放在原型鏈上 protytype
// ES6 類的定義的實例化
class Animal {
constructor(type) { // 構造函數,用來傳參
this.type = type
}
eat() {
console.log('I am eat food')
}
}
let dog = new Animal('dog')
let monkey = new Animal('monkey')
console.log(dog)
console.log(monkey)
dog.eat()
monkey.eat()
console.log(typeof Animal) // function
二、ES5 中怎樣讀寫一個屬性?ES6 如何實現?
ES5 中幾乎無法實現屬性讀寫保護。
// ES6 屬性讀寫保護,利用get 和 set 配合閉包實現
let _age = 4
class Animal {
constructor(type) {
this.type = type
}
get age() { // 只讀 --ES6 允許屬性放在類的頂層 前面一定要加 get 或 set,使之與方法區別開來
return _age //閉包實現。 返回值變量名需和訪問時的變量名不同
}
set age(val) { // --ES6 允許屬性放在類的頂層 前面一定要加 get 或 set,使之與方法區別開來
if (val < 7 && val > 4) { // 滿足該條件可寫
_age = val
}
}
eat() {
console.log('I am eat food')
}
}
let dog = new Animal('dog')
console.log(dog.age) // 注意調用方法,此處以屬性調用
dog.age = 8
console.log(dog.age) // 注意調用方法,此處以屬性調用
三、ES5中怎樣操作一個方法?ES6 如何操作?
什麼是靜態方法?不屬於實例,而是屬於類。
// ES5 添加靜態方法及調用靜態方法示例
let Animal = function (type) {
this.type = type
}
Animal.prototype.eat = function () {
// this.walk() // 此時this指的是Animal的實例對象,而實例對象上並沒有walk方法
Animal.walk() // 靜態方法的引用
console.log('I am eat food')
}
// ES5 增加靜態方法
Animal.walk = function () {
console.log('I am walking')
}
let dog = new Animal('dog')
dog.eat()
dog.walk() // dog.walk is not a function
// ES6 添加靜態方法及調用靜態方法示例
class Animal {
constructor(type) {
this.type = type
}
eat() {
Animal.walk() // 引用靜態方法
console.log('I am eat food')
}
static walk() { // ES6 類的靜態方法定義
console.log('I am walking')
}
}
let dog = new Animal('dog')
dog.eat()
如果方法依賴於對象的某些屬性或方法,也就是說方法內部要引用實例對象的信息,要用類的靜態方法,類的靜態方法拿不到當前的實例對象。
四、ES5 中怎麼繼承另一個類?ES6中如何實現?
// ES5 繼承
let Animal = function (type) {
this.type = type
}
Animal.prototype.eat = function () {
Animal.walk() // 靜態方法的引用
console.log('I am eat food')
}
Animal.walk = function () {
console.log('I am walking')
}
// 定義子類
let Dog = function () {
Animal.call(this, 'dog') // 執行/初始化 Animal(父類) 構造函數,不涉及原型型
this.run = function () {
console.log('I can run')
}
}
// 至此爲部分繼承,只會繼承 Animal 構造函數中的屬性和方法
// 繼續 將Dog 原型鏈上的屬性和方法指向Animail 以實現完全繼承
Dog.prototype = Animal.prototype;
let dog = new Dog('dog')
dog.eat()
// ES6 繼承
class Dog extends Animal {
constructor(type) { // 顯式調用構造函數
super(type)
this.age = 2 // 如果子類構造函數是空的
}
}
let dog = new Dog('dog')
dog.eat()