JS中的类Class的总结
1、雖然ES6類表面上看起來是可以支持正式的面向對象編程,但是實際上它背后使用的仍然是原型和構造函數的概念
2、類與函數之間的區別
與函數的定義不同的是,雖然函數聲明可以提升,但類的定義不可以提升
函數受函數作用域限制,而類受塊作用域限制
類表達式的名稱是可選的,把類表達式賦值給變量后,可以通過屬性取得類表達式的名稱字符串,但不能在表達式作用域外部訪問這個標識符
let Person = class PersonName {
identify() {
console.log(Person.name, PersonName.name)
}
}
let p = new Person()
p.identify()
console.log(Person.name)
console.log(PersonName)
3、constructor關鍵字
constructor關鍵字用于在類定義塊內部創建類的構造函數,方法名constructor會告訴解釋器在使用new操作符創建類的新實例時,應該調用這個函數。構造函數的定義不是必須的,不定義構造函數相當于將構造函數定義為空函數。
4、實例化
使用new操作符實例化Person的操作等于使用new調用其構造函數。唯一可感知的不同之處就是,Javascript解釋器知道使用new和類意味著應該使用constructor函數進行實例化
使用new調用類的構造函數會執行如下操作
(1)在內存中創建一個新對象
(2)這個新對象內部的[[ Prototype ]]指針被賦值為構造函數的prototype屬性
(3) 構造函數內部的this被賦值為這個新對象(即this指向新對象)
(4)執行構造函數內部的代碼(給新對象添加屬性)
(5)如果構造函數返回非空對象,則返回該對象;否則,返回剛創建的新對象
看看高程上關于對象和原型的部分
class Animal {}
class Person {
constructor() {
console.log('person ctor')
}
}
class Vegetable {
constructor() {
this.color = 'orange'
}
}
let a = new Animal()
let p = new Person()
let v = new Vegetable()
console.log(v.color)
類實例化時傳入的參數會作用構造函數的參數,如果不需要參數,則類名后面的括號也是可選的
class Person {
constructor(name) {
console.log(arguments.length)
this.name = name || null
}
}
let p1 = new Person
console.log(p1.name)
let p2 = new Person()
console.log(p2.name)
let p3 = new Person('Jake')
console.log(p3.name)
默認情況下,類構造函數會在執行之后返回this對象,構造函數返回的對象會被用作實例化的對象,如果沒有什么引用新創建的this對象,那么這個對象會被銷毀,不過,如果返回的不是this對象,而是其他對象,那么這個對象不會通過instanceof操作符檢測出跟類有關聯,因為這個對象的原型指針并沒有修改
class Person {
constructor(override) {
this.foo = 'foo'
if(override) {
return {
bar: 'bar'
}
}
}
}
let p1 = new Person(),
p2 = new Person(true);
console.log(p1)
console.log(p1 instanceof Person)
console.log(p2)
console.log(p2 instanceof Person)
類構造函數與構造函數的主要區別是:調用類構造函數必須使用new操作符,而普通構造函數如果不使用new調用,那么就會以全局的this(通常是window)作為內部對象
類通過typeof操作符檢測類標識符,表明它是一個函數
class Person {}
console.log(Person)
console.log(typeof Person)
console.log(Person.prototype)
console.log(Person === Person.prototype.constructor)
在類的上下文中,類本身在使用new調用時就會被當成構造函數
類中定義的constructor方法不會被當作構造函數,在對它使用instanceof操作符時會返回false
如果在創建實例時直接將類構造函數當成普通構造函數來使用,那么instanceof操作符的返回值會反轉
class Person {}
let p1 = new Person()
console.log(p1.constructor === Person)
console.log(p1 instanceof Person)
console.log(p1 instanceof Person.constructor)
let p2 = new Person.constructor()
console.log(p2.constructor === Person)
console.log(p2 instanceof Person)
console.log(p2 instanceof Person.constructor)
5、實例成員
每個實例都對應一個唯一的成員對象,所有成員都不會在原型上共享
class Person {
constructor() {
this.name = new String('Jack')
this.nicknames = ['Jake', 'J-Dog']
}
}
let p1 = new Person(),
p2 = new Person();
p1.sayName()
p2.sayName()
console.log(p1.name === p2.name)
console.log(p1.sayName === p2.sayName)
console.log(p1.nicknames === p2.nicknames)
6、為了在實例間共享方法,類定義語法把在類塊中定義的方法作為原型方法
class Person {
constructor() {
// 添加到this的所有內容都會存在于不同的實例上
this.locate = () => console.log('instance')
// 在類塊中定義的所有內容都會定義在類的原型上
locate() {
console.log('prototype')
}
}
}
類定義也支持獲取和設置訪問器,語法和普通對象一樣:
class Person {
set name(newName) {
this.name_ = newName
}
get name() {
return this.name_
}
}
let p = new Person()
p.name = 'Jake'
console.log(p.name)
7、靜態類方法
靜態類成員在類定義中使用static關鍵字作為前綴
在靜態成員中,this引用類自有約定跟原型成員一樣
靜態類方法非常適合作為實例工廠
8、類的繼承
ES6中原生支持了類繼承,雖然使用了新的語法,但是背后使用的還是原型鏈
類可以繼承類,也可以繼承普通的構造函數(保持向后兼容)
派生類都會通過原型鏈訪問到類和原型上定義的方法
9、super
派生類的方法可以通過super關鍵字引用他們的原型
關鍵字只能在派生類中使用,而且僅限于類構造函數、實例方法和靜態方法內部
在類構造函數中使用super可以調用父類構造函數
10、抽象基類
11、類混入
總結
以上是生活随笔為你收集整理的JS中的类Class的总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2017招行10元风暴礼品更新 看看都有
- 下一篇: 林志颖父子出车祸 特斯拉燃起大火!最新伤