重學ES6(二):ES5和ES6中Class類的相同與不同


ES5和ES6中Class類的相同與不同  

先說結論,簡而言之ES5用function定義類,ES6用class定義類,class的本質是function,ES6中的類只是語法糖,它並沒有改變ES5下類實現的本質。

類的定義

ES5

// ES5函數來描寫類
// 聲明類
let Animal = function (type) {
  this.type = type
  // 定義實例方法
  this.drink = function () {
    console.log('drink')
  }
}

// 定義原型方法
Animal.prototype.eat = function () {
  console.log('eat food')
}

// 實例化
let dog = new Animal('dog')
let monkey = new Animal('monkey')

ES6

// ES6 class
// class的本質是ES5用原型鏈聲明類的語法糖
class Animal {
  constructor (type) {
    this.type = type
  }
  eat () {
    console.log('eat food')
  }
}

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

ES6類中的set和get方法

  • set用於設置屬性(無返回值)
  • get用於讀取屬性(有返回值)
let _age = 4
class Animal {
  constructor (type) {
    this.type = type
  }
  get age () {
    return _age
  }
  set age (val) {
    this.realage = val
  }
  eat () {
    console.log('eat food')
  }
}

let dog = new Animal('dog')
console.log(dog.age) // 4
dog.age = 5 // 未生效 get定義的為只讀屬性
console.log(dog.age) // 4
console.log(dog.realage) // 5

ES5類中的 實例方法&原型方法&靜態方法

  • 實例方法只有實例可以調用

  • 實例方法可以調用靜態方法,不能調用原型方法

  • 原型方法可以被實例和構造函數訪問到

  • 原型方法只可以調用靜態方法

  • 靜態方法只有構造函數可以調用

 

ES5中定義三種方法及調用關系

let Animal = function (type) {
  this.type = type
  // 實例方法
  this.drink = function () {
    // 實例方法可調用類的靜態方法
    Animal.walk()
    console.log('drink')
  }
}

// 原型方法
Animal.prototype.eat = function () {
  // 原型方法可調用類的靜態方法
  Animal.walk()
  console.log('eat food')
}

// 靜態方法
Animal.walk = function () {
  console.log('walking')
}

let dog = new Animal('dog')
dog.drink() // walking drink
dog.eat() // walking eat food
Animal.walk() // walking靜態方法只能由<類自身&實例方法&原型方法>調用,實例對象無法調用
// dog.walk() // dog.walk is not a function  實例對象無法調用靜態方法

 

ES6類中的 實例方法&原型方法&靜態方法

  • 實例方法=原型方法 類中直接定義的實例方法默認就是ES5中的原型方法(語法糖)

  • 靜態方法用static前綴定義

  • 靜態方法只有構造函數可以調用,原型方法是實例和構造函數都可以調用,是共享的方法。

class Animal {
  constructor (type) {
    this.type = type
  }
  // 定義實例對象的方法
  eat () {
    // 使用靜態方法,以類形式訪問,而非this訪問
    Animal.walk()
    console.log('eat food')
    console.log(this.type) // 類的例實例對象的方法可以獲取到實例對象的信息,輸出dog
  }
  // static 定義類的靜態方法
  static walk () {
    console.log('walking')
    console.log(this.type) // 類的靜態方法無法獲取到實例對象的信息,輸出undefined
  }
}
let dog = new Animal('dog')
dog.eat() // walking ; undefined ; eat food ; dog
Animal.walk() // walking ; undefined ;
dog.walk() // dog.walk is not a function
// 得出結論:需要訪問實例對象的信息時用實例對象的方法,否則使用static靜態方法
// 實例方法就是只有實例可以調用,靜態方法只有構造函數可以調用,原型方法是實例和構造函數都可以調用,是共享的方法。

 

ES5 子類

  • .call方法指向父類

  • 設置原型鏈指向相同

let Animal = function (type) {
  this.type = type
  // 實例方法
  this.drink = function () {
    // 實例方法可調用類的靜態方法
    Animal.walk()
    console.log('drink')
  }
}

// 原型方法
Animal.prototype.eat = function () {
  // 原型方法可調用類的靜態方法
  Animal.walk()
  console.log('eat food')
}

// 靜態方法
Animal.walk = function () {
  console.log('walking')
}

let Dog = function () {
  // 初始化父類的構造函數,call的作用是改變this指向dog的實例
  Animal.call(this, 'dog')
  this.run = function () {
    console.log('run')
  }
}

// 兩個原型鏈指向相同,子類才可以用父類的方法
Dog.prototype = Animal.prototype

let dog = new Animal('dog')
dog.eat()  // 實例對象能調用類定義在原型上的實例對象的方法
// dog.walk() // 實例對象不能調用類的靜態方法

let realdog = new Dog('realdog')
realdog.eat()
realdog.run()

 

ES6 子類

  • extends定義子類,super指向父類的原型對象,可以調用父類的屬性和方法。

class Animal {
  constructor (type, age) {
    this.type = type
    this.age = age
  }
  detail () {
    console.log(this.type + ' ' + this.age)
  }
}

class Dog extends Animal {
  // 定義子類的構造函數
  constructor (type, age, sex) {
    // super()要和父類的constructor一致
    // super關鍵字表示調用父類的構造方法,也就是父類constructor中的內容
    super(type, age)
    this.sex = sex
  }
  ndetail () {
    console.log(this.type + ' ' + this.age + ' ' + this.sex)
  }
}

// let cat = new Animal('cat', 20)
// cat.detail()
let dog = new Dog('dog', 5, 'gong')
dog.ndetail()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM