ES6(四)—— Class

目錄

  • Classes6

    • 類的使用【聲明、屬性、方法、繼承】
    • Basic Syntax —— 怎麼聲明一個類?函數

      • ES5
      • ES6
      • 類和構造函有什麼區別?
    • Setters & Getters —— 如何讀寫屬性?學習

      • ES5
      • ES6this

        • getter / setter 是讀寫屬性
    • Static Methods —— 如何操做一個方法?spa

      • ES5
      • ES6
      • 開發中何時用對象實例方法,何時用靜態方法?
    • Sub Classes —— 怎麼繼承另外一個類?prototype

      • ES5
      • ES6
  • ES6-ES10學習版圖

類的使用【聲明、屬性、方法、繼承】

Basic Syntax —— 怎麼聲明一個類?

ES5

let Animal = function (type) {
    this.type = type
    this.eat = function () {
        console.log('i am eat food')
    }
}

let dog = new Animal('dog')
let monkey = new Animal('monkey')

console.log(dog.eat()) //i am eat food
console.log(monkey.eat()) //i am eat food

monkey.eat = function () {
    console.log('error')
}
console.log(dog.eat()) //i am eat food
console.log(monkey.eat()) //error
// eat若是實例化以後進行修改,修改了dog的,那麼monkey的不會改變,這樣就失去了繼承的概念。若是是公共方法那麼不要寫在類的私有方法裏面。

因此要把公共方法放在原型對象上面code

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.eat()) //i am eat food
console.log(monkey.eat()) //i am eat food
monkey.constructor.prototype.eat = function () {
    console.log('error')
}
console.log(dog.eat()) //error
console.log(monkey.eat()) //error

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.eat())
console.log(monkey.eat())

類和構造函有什麼區別?

沒有區別,class只是ES5用原型鏈聲明構造函數的 語法糖
console.log(typeof Animal) //function

Setters & Getters —— 如何讀寫屬性?

ES5

沒法實現讀寫屬性的攔截操做,只讀屬性等很差實現對象

ES6

getter / setter 是讀寫屬性

讀屬性blog

class Animal {
    constructor (type) {
        this.type = type
    }
    //age 前面加一個get / set,就變成了屬性,es6支持屬性提高到函數體最頂層,能夠不所有寫到constructor裏面
    //get是隻讀屬性
    get age () {
        return 4
    }
    eat () {
        console.log('i am eat food')
    }
}

let dog = new Animal('dog')
console.log(dog.age) // 4
dog.age = 5
console.log(dog.age) // 4 對age的賦值並無生效

寫屬性繼承

let _age = 4
class Animal {
    constructor (type) {
        this.type = type
    }
    // 讀取
    get age () {
        return _age //返回值和屬性名age不要同樣
    }
    // 寫入
    set age (val) {
        if (val < 7 && val > 4) {
            _age = val //返回值和屬性名age不要同樣
        }
    }
    eat () {
        console.log('i am eat food')
    }
}

let dog = new Animal('dog')
console.log(dog.age) // 4
dog.age = 5 // 符合條件,修改了age屬性的值
console.log(dog.age) // 5
dog.age = 8 // 不符合條件,沒有修改age屬性的值
console.log(dog.age) // 5

Static Methods —— 如何操做一個方法?

  • 對象實例方法
  • 類的靜態方法

ES5

let Animal = function (type) {
    this.type = type
}

// 對象實例方法
Animal.prototype.eat = function () {
    Animal.walk() //這裏不用this,是由於這裏的this,指的是實例對象,而walk方法是在構造函數上,不在實例對象上
    console.log('i am eat food')
}

// 添加靜態方法,經過類是能夠訪問的,可是沒法經過實例對象訪問
Animal.walk = function () {
    console.log('i am walking')
}

let dog = new Animal('dog')
dog.eat()
//i am walking
//i am eat food
dog.walk() // dog.walk is not a function 報錯

ES6

static標識符能夠實現

class Animal {
    constructor (type) {
        this.type = type
    }
    // 對象實例方法,類中直接定義方法就是實例對象的方法
    eat () {
        Animal.walk() 
        console.log(this) // 這裏的類指的是Animal,不能在這裏使用this.type,由於Animal上面沒有type屬性,其原型對象上有type屬性
        console.log('i am eat food')
    }
    // 添加靜態方法,是經過static標識符進行區分的
    static walk () {
        console.log('i am walking')
    }
}

let dog = new Animal('dog')
dog.eat()
//i am walking
//i am eat food

開發中何時用對象實例方法,何時用靜態方法?

若是此函數內部有要使用實例對象的屬性和方法的時候,那麼必須定義爲 類的實例對象方法
若是此函數內部不須要實例對象的內容,就使用 類的靜態方法

Sub Classes —— 怎麼繼承另外一個類?

面向對象之因此強大,就是由於繼承。

ES5

  1. 先繼承Animal構造函數內部的屬性和方法
  2. 再繼承原型鏈上的屬性和方法
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')
}
// 聲明一個Dog構造函數,其繼承Animal構造函數的,將Animal構造函數運行一下,並將其this指向Dog構造函數
let Dog = function () {
    // 1.初始化父類的構造函數,使用call是改變this的指向Dog的實例,後面是傳入的參數,有多少依此日後排便可
    // 這裏只能繼承Animal構造函數內部的屬性和方法
    Animal.call(this, 'dog')
}
// 2.剩下一部分掛載在原型鏈上的繼承,須要把Dog的原型鏈指向Animal的原型鏈--引用類型
Dog.prototype = Animal.prototype
let dog = new Dog('dog')
dog.eat()
//i am walking
//i am eat food

ES6

extends能夠實現

class Animal {
    constructor (type) {
        this.type = type
    }
    eat () {
        Animal.walk()
        console.log(this.type + ' eat food')
    }
    static walk () {
        console.log('i am walking')
    }
}

// 用extends實現了繼承,用其來表示Dog是Animal的子類
class Monkey extends Animal {
    // 默認執行了下面的語句,若是構造函數沒有新增屬性這樣寫,那麼能夠不用寫
    // constructor (type) {
        // super(type) //繼承父類要執行父類的構造函數,專用方法
    // }
}
class Dog extends Animal {
    constructor (type) {
        // super必須在構造函數第一行,不然報錯,並且必須傳參數
        super(type) 
        this.age = 2
    }
    hello () {
        // super對象始終指向父類,調用它就是調用了父類的構造函數
        super.eat()
        console.log('and say hello')  
    }
}

let dog = new Dog('dog')
let monkey = new Monkey('monkey')
dog.eat()
monkey.eat()
// i am walking
// dog eat food
// i am walking
// monkey eat food
dog.hello()
// i am walking
// dog eat food
// and say hello

學習版圖

ES6-10.png

相關文章
相關標籤/搜索