【ES6系列】Class

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()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章