1. 程式人生 > 其它 >Class(類)

Class(類)

技術標籤:es6es6

前言

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 這個模板,例項化出來的物件。例項化出來的物件擁有類預先訂製好的結構和功能。

  1. constructor是一個建構函式方法,建立物件時自動呼叫該方法
  2. constructor是預設存在的,可以省略,程式也可以呼叫
  3. this指的是例項化物件
  4. 類中宣告的方法不能加function關鍵字
  5. 方法之間不要用逗號分隔,否則會報錯

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作用

  1. 子類使用構造器constructor的時候,必須使用super關鍵字,用來擴充套件構造器
  2. 子類同名方法會覆蓋父類同名方法,使用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關鍵字

  1. static關鍵字是類的方法
  2. 只能通過類名來呼叫,不能被例項物件呼叫
  3. 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)。