亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JS高級程序設計之class繼承重點詳解

 更新時間:2022年07月06日 15:16:23   作者:掘金安東尼  
這篇文章主要為大家介紹了JS高級程序設計之class繼承重點示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

前文已提過:在 class 出現(xiàn)之前,JavaScript 實現(xiàn)繼承是件麻煩事,構造函數(shù)繼承有加上原型上的函數(shù)不能復用的問題;原型鏈繼承又存在引用值屬性的修改不獨立的問題;組合繼承又存在兩次調用構造函數(shù)的問題,寄生組合繼承,寫起來又太麻煩了,總之,在 class 出現(xiàn)前,JavaScipt 實現(xiàn)繼承真是件麻煩事兒。

然而,class 的出現(xiàn)真的改變這一現(xiàn)狀了嗎?

不如往下看。

寫法

與函數(shù)類型相似,定義類也有兩種主要方式:類聲明和類表達式。

// 類聲明 class Person {}

// 類表達式 const Animal = class {};

不過,與函數(shù)定義不同的是,雖然函數(shù)聲明可以提升,但類定義不能。

與函數(shù)構造函數(shù)一樣,多數(shù)編程風格都建議類名的首字母要大寫,以區(qū)別于通過它創(chuàng)建的實例。

類可以包含:

  • 構造函數(shù)方法
  • 實例方法
  • 獲取函數(shù)
  • 設置函數(shù)
  • 靜態(tài)類方法

這些項都是可選的

constructor

class Person { 
    constructor(name) {
        this.name = name
        console.log('person ctor');
    }
}
let p1 = new Person("p1")

constructor 會告訴解釋器 在使用 new 操作符創(chuàng)建類的新實例時,應該調用這個函數(shù)。

等同于

function Person(name){
    this.name = name
    console.log('person ctor')
}
let p1 = new Person("p1")

類構造函數(shù)與構造函數(shù)的主要區(qū)別是,這樣寫會報錯:

class Animal {}
let a = Animal(); // TypeError: class constructor Animal cannot be invoked without 'new'

所以,new 操作符是強制要寫的;

使用 new 時,原理與 new 一個對象也是一樣的,因為太重要了,再強調一遍:

(1) 在內存中創(chuàng)建一個新對象。

(2) 這個新對象內部的[[Prototype]]指針被賦值為構造函數(shù)的 prototype 屬性。

(3) 構造函數(shù)內部的 this 被賦值為這個新對象(即 this 指向新對象)。

(4) 執(zhí)行構造函數(shù)內部的代碼(給新對象添加屬性)。

(5) 如果構造函數(shù)返回非空對象,則返回該對象;否則,返回剛創(chuàng)建的新對象。

特性

從各方面來看,ECMAScript 類就是一種特殊函數(shù)。

我們可以用 typeof 打印試試:

class Person {} 
console.log(typeof Person); // function

也可以用 instanceof 檢查它的原型鏈

class Person {} 
let p = new Person()
console.log(p instanceof Person); // true

通過 class 構造的每個實例都對應一個唯一的成員對象,這意味著所有成員都不會在原型上共享;

class Person {
 constructor() {
 this.name = new String('Jack');
 this.sayName = () => console.log(this.name);
 }
}
let p1 = new Person();
let p2 = new Person();
console.log(p1.name === p2.name) // false
console.log(p1.sayName === p2.sayName) // false

如果想要共享,就改寫成方法,寫在 constructor 外面:

class Person {
 constructor() {
 this.name = new String('Jack');
 }
 sayName(){
      console.log(this.name);
 }
}
let p1 = new Person();
let p2 = new Person();
console.log(p1.sayName === p2.sayName) // true

我們可以在方法前面加 static 關鍵字,實現(xiàn):靜態(tài)類成員。我們不能在類的實例上調用靜態(tài)方法,只能通過類本身調用。不做贅述。

繼承

ECMAScript 6 新增特性中最出色的一個就是原生支持了類繼承機制。雖然類繼承使用的是新語法,但背后依舊使用的是原型鏈。

讓我們再回顧構造函數(shù)繼承和原型鏈繼承 2 個經典的問題:

① 構造函數(shù)繼承的問題:構造函數(shù)外在原型上定義方法,不能重用

function SuperType(){}
SuperType.prototype.sayName = ()=>{console.log("bob")}
function SubType(){
    SuperType.call(this) // 構造函數(shù)繼承
}
let p1 = new SubType()
console.log(p1.sayName()) // Uncaught TypeError: p1.sayName is not a function

而原型鏈繼承可以解決這一點:

function SuperType(){}
SuperType.prototype.sayName = ()=>{console.log("bob")}
function SubType(){}
SubType.prototype = new SuperType()  // 原型鏈繼承
let p1 = new SubType()
console.log(p1.sayName()) // bob

② 原型鏈繼承的問題:原型中包含的引用值會在所有實例間共享。

function SuperType(){
    this.name = ["bob","tom"];
}
function SubType(){}
SubType.prototype = new SuperType()  // 原型鏈繼承
let p1 = new SubType()
p1.name.push("jerry")
let p2 = new SubType()
console.log(p2.name) //  ['bob', 'tom', 'jerry']

而構造函數(shù)繼承可以解決這一點:

function SuperType(){
    this.name = ["bob","tom"];
}
function SubType(){
    SuperType.call(this) // 構造函數(shù)繼承
}
let p1 = new SubType()
p1.name.push("jerry")
let p2 = new SubType()
console.log(p2.name) //  ['bob', 'tom']

class 繼承有這兩個問題嗎??

代碼一試便知:

class SuperType{}
SuperType.prototype.sayName = ()=>{console.log("bob")}
class SubType extends SuperType{
}
let p1 = new SubType()
p1.sayName() // bob

問題①,沒有問題,在構造函數(shù)外寫的原型繼承,公共方法還是能訪問的!!

class SuperType{
    constructor(){
        this.name=["bob","tom"]
    }
}
class SubType extends SuperType{
}
let p1 = new SubType()
let p2 = new SubType()
p1.name.push("Jerry")
console.log(p2.name) //  ['bob', 'tom']

問題②,沒有問題,在 constructor 的引用值屬性,修改不會產生干涉??!

class 繼承完美的解決了構造函數(shù)繼承的問題,和原型鏈繼承的問題,寫起來也沒有組合繼承、寄生繼承那么麻煩,如果非得用 JS 模擬面向對象編程,class 必不可少!!

題外話

其實寫 Class C 和 C.prototype 一起寫是很危險的:明明都在操作面向對象的類了,還要操作原型鏈。類操作和原型操作是兩種不同的設計思路,有興趣可見本瓜一年前的一篇文章:“類”設計模式和“原型”設計模式——“復制”和“委托”的差異

以上就是JS高級程序設計之class繼承重點詳解的詳細內容,更多關于JS高級程序設計class繼承的資料請關注腳本之家其它相關文章!

相關文章

最新評論