Class(類)
阿新 • • 發佈:2020-12-29
前言
ES6引入了
Class
(類)這個概念,作為物件的模板。通過class關鍵字,可以定義類。
但是JS 中並沒有一個真正的 class
原始型別, class
僅僅只是對原型物件運用語法糖。所以,只有理解如何使用原型物件實現類和類繼承,才能真正地用好 class
。
基本語法
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
Say(){
return 'My name is ' + this .name;
}
}
var person1 = new Person('Ethel',18);
console.log(person1.Say());//My name is Ethel
程式碼解析
person1
是通過類Person
例項化出來的物件。物件person1
是按照類Person
這個模板,例項化出來的物件。例項化出來的物件擁有類預先訂製好的結構和功能。
constructor
是一個建構函式方法,建立物件時自動呼叫該方法constructor
是預設存在的,可以省略,程式也可以呼叫this
指的是例項化物件- 類中宣告的方法不能加
function
關鍵字 - 方法之間不要用逗號分隔,否則會報錯
class類與原型的關係
class
類本質上就是一個函式,自身指向的就是建構函式
console.log(typeof Person);// function
console.log(Person.prototype.constructor === Person);//true
class
類是建構函式的另一種寫法,仍然存在prototype
方法
console.log(Person.prototype);//object
可以通過原型prototype
修改類方法和新增方法
Person.prototype.Say = function(){
return 'My name is ' + this .name+',我是原型prototype宣告同樣的Say方法,把原有Say方法覆蓋了';
}
person2 = new Person('Frank',20);
console.log(person2.Say());//My name is Frank,我是原型prototype宣告同樣的Say方法,把原有Say方法覆蓋了
Person.prototype.Go = function(){
return 'I am ' + this.age + ' years old';
}
console.log(person2.Go());//I am 20 years old
還可以通過Object.assign
方法來為物件動態增加方法
Object.assign(Person.prototype,{
Eat:function(){
return this.name;
},
Run:function(){
return this.age;
}
})
person3 = new Person('Allen',20);
console.log(person3.Eat());//Allen
console.log(person3.Run());//20
也可以使用例項物件的__proto__
屬性新增類的方法
person3 = new Person('Allen',20);
person4 = new Person('Morgan',21);
person3.__proto__.Play = function(){
return this.name;
}
console.log(person3.Play());// Allen
console.log(person4.Play());// Morgan
例項屬性和原型屬性
例項屬性:constructor
裡面的屬性為例項屬性,即定義在this
物件上
原型屬性:除去例項屬性都稱為原型屬性,即定義在class
類上
hasOwnProperty
方法:可以通過hasOwnProperty()
方法進行判斷屬性是否是例項屬性
in
操作符:能夠訪問到屬性時返回true
,無論是例項屬性還是原型屬性
class Person{
constructor(person1,person2){
this.person1 = person1;
this.person2 = person2;
}
Say(){
return person1+person2;
}
}
var box = new Person('Emily','Kristina');
console.log(Person.hasOwnProperty("person1"));//true
console.log(Person.hasOwnProperty("person1"));//true
console.log(Person.hasOwnProperty("Say"));//false
console.log("person1" in Person);//true
console.log("person2" in Person);//true
console.log("Say" in Person);//true
console.log("Go" in Person);//false
class類的繼承
通過extends
關鍵字實現類的繼承
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
getName(){
return this.name;
}
getAge(){
return this.age;
}
}
class Student extends Person{
getName(){
return '我覆蓋了父級的方法,'+ this.name;
}
getScore(){
return '我是子級新增的方法,'+this.name;
}
}
var stu1 = new Student('Ethel',18);
console.log(sut1.getName());// 我覆蓋了父級的方法,Ethel
console.log(sut1.getAge());//18
console.log(sut1.getScore());// 我是子級新增的方法,Ethel
通過super
關鍵字進行拓展父類構造器或方法
super作用
- 子類使用構造器
constructor
的時候,必須使用super
關鍵字,用來擴充套件構造器 - 子類同名方法會覆蓋父類同名方法,使用
super
關鍵字後則可以呼叫到父類的同名函式
class Person{
constructor(name){
this.name = name;
}
getName(){
console.log('我是父級類getName方法輸出來的');
}
getAge(){
console.log(this.age);
}
}
class Student extends Person{
constructor(name,age,sex){
super();//必須先呼叫super,才能使用constructor,才能使用this物件
this.name = name;
this.age = age;
this.sex = sex;
}
getName(){
super.getName();//呼叫super,才能呼叫父類同名函式getName
console.log('我是子級類getName方法輸出來的');
}
}
var stu1 = new Student('Ethel',18);
stu1.getName();
// 我是父級類getName方法輸出來的
// 我是子級類getName方法輸出來的
static關鍵字
static
關鍵字是類的方法- 只能通過類名來呼叫,不能被例項物件呼叫
static
方法也可以被繼承
class Person{
constructor(name,age){
this.name = name;
this.age = age;
}
static getAge(){
console.log('我是靜態屬性static');
}
}
class Student extends Person{}
var stu1 = new Student('Ethel',2);
Person.getAge();//我是靜態屬性static
Student.getAge();//我是靜態屬性static
stu1.getAge();//stu1.getAge is not a function
class 例項化的背後原理
使用 class
的語法,讓開發者告別了使用 prototype
模仿面向物件的時代。但是,class
並不是 ES6
引入的全新概念,它的原理依舊是原型繼承。
typeof class == "function"
通過型別判斷,我們可以得知,
class
的並不是什麼全新的資料型別,它實際只是function
(或者說object
)。