最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JS面向?qū)ο笾畯膒rototype到class再到私有屬性詳解

 更新時間:2026年01月21日 10:28:53   作者:止觀止  
JavaScript的原型prototype是JavaScript中的一個重要概念,它是一種特殊類型的對象,每個JavaScript對象都有一個原型對象,這篇文章主要介紹了JS面向?qū)ο笾畯膒rototype到class再到私有屬性的相關(guān)資料,需要的朋友可以參考下

前言

這一篇將探討 JavaScript 中的面向?qū)ο缶幊蹋∣OP)。對于從 Java、C# 轉(zhuǎn)過來的開發(fā)者來說,以前 JS 的原型繼承機制往往讓人摸不著頭腦。ES6 引入的 class 關(guān)鍵字極大地降低了心智負擔(dān),雖然它本質(zhì)上是“語法糖”,但它讓代碼結(jié)構(gòu)更加清晰、標(biāo)準(zhǔn)。

1. 引言

在 ES6(ES2015)之前,JavaScript 想要實現(xiàn)“類”和“繼承”是非常痛苦的。因為 JS 本質(zhì)是基于原型的,而不是基于類的。如果你在網(wǎng)上搜“JS 繼承五種寫法”,你會發(fā)現(xiàn)組合繼承、寄生組合繼承等讓人頭禿的代碼:

// ES5 之前的“恐怖”繼承寫法
function Parent(name) { this.name = name; }
Parent.prototype.say = function() { console.log(this.name); };

function Child(name, age) {
    Parent.call(this, name); // 借用構(gòu)造函數(shù)
    this.age = age;
}
Child.prototype = new Parent(); // 原型鏈繼承
Child.prototype.constructor = Child; // 修正 constructor 指向

這不怪開發(fā)者,怪語言設(shè)計太底層。

ES6 引入了 class 關(guān)鍵字,終于給了我們一個**“看起來像樣”的面向?qū)ο笳Z法。雖然它底層依然是原型繼承,但它把復(fù)雜的細節(jié)封裝了起來。到了 ES2022,甚至支持了真正的私有屬性**。

本文將帶你掌握:

  1. 為什么 class 只是語法糖,但必須得用?
  2. 如何優(yōu)雅地使用 extendssuper 實現(xiàn)繼承?
  3. 如何使用 # 定義真正的私有變量。

2. 正文

2.1 ES5 的“原型”寫法(快速回顧)

在深入 class 之前,只需記住一點:ES5 的類本質(zhì)是一個構(gòu)造函數(shù)。

function Animal(name) {
    this.name = name;
}
// 方法掛載在原型上,所有實例共享
Animal.prototype.speak = function() {
    console.log(this.name + " makes a noise.");
};

這種寫法把屬性(構(gòu)造函數(shù)內(nèi))和方法(原型上)分開了,對于 Java/C++ 程序員來說非常不直觀。

2.2 ES6class—— 更加優(yōu)雅的語法糖

ES6 的 class 可以看作是一個語法糖,它讓對象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z法。

1. 定義類與構(gòu)造函數(shù)

class Animal {
    // 構(gòu)造方法
    constructor(name) {
        this.name = name;
    }

    // 實例方法(等同于定義在 prototype 上)
    speak() {
        console.log(`${this.name} makes a noise.`);
    }
}

const a = new Animal("Dog");
a.speak(); // "Dog makes a noise."

注意:類的方法之間不需要逗號分隔,加了逗號會報錯!

2. 靜態(tài)方法

使用 static 關(guān)鍵字定義的方法屬于本身,而不是實例。這非常適合工具類方法。

class Animal {
    constructor(name) { this.name = name; }
    
    // 靜態(tài)方法
    static compare(a, b) {
        return a.name === b.name;
    }
}

const dog1 = new Animal("Dog");
const dog2 = new Animal("Dog");

// 正確:通過類調(diào)用
console.log(Animal.compare(dog1, dog2)); // true

// 錯誤:實例無法調(diào)用
// dog1.compare(); // TypeError

2.3 繼承與super的正確姿勢

ES6 使用 extends 關(guān)鍵字實現(xiàn)繼承,比 ES5 的原型鏈篡改要簡單得多。

class Dog extends Animal {
    constructor(name, breed) {
        // 必須先調(diào)用 super(),否則會報錯!
        // super 代表父類的構(gòu)造函數(shù)
        super(name); 
        this.breed = breed;
    }

    speak() {
        // 調(diào)用父類的方法
        super.speak(); 
        console.log(`${this.name} barks.`);
    }
}

const d = new Dog("Rex", "Bulldog");
d.speak();
// 輸出:
// "Rex makes a noise."
// "Rex barks."

核心坑點

在子類的 constructor 中,必須在使用 this 之前調(diào)用 super()。這是因為子類沒有自己的 this 對象,而是繼承父類的 this 對象。

2.4 私有屬性與新特性

在很長一段時間里,JS 沒有真正的私有屬性(private)。大家只能靠命名約定(比如 _name)來表示“請勿訪問”,但這是防君子不防小人的。

1. ES2022:私有字段

現(xiàn)在,我們可以在屬性名前加 #(井號)來定義真正的私有屬性。帶 # 的屬性是類作用域私有的,外部無法訪問。

class BankAccount {
    #balance = 0; // 私有屬性

    constructor(initial) {
        this.#balance = initial;
    }

    deposit(amount) {
        this.#balance += amount;
    }

    getBalance() {
        return this.#balance;
    }
}

const myAccount = new BankAccount(100);
myAccount.deposit(50);
console.log(myAccount.getBalance()); // 150

// console.log(myAccount.#balance); // 報錯!SyntaxError: Private field '#balance' must be declared in an enclosing class

2. new.target

用于檢測函數(shù)或構(gòu)造函數(shù)是否是通過 new 關(guān)鍵字調(diào)用的。它可以用來限制類必須被實例化,或者防止直接調(diào)用抽象類。

class Parent {
    constructor() {
        if (new.target === Parent) {
            throw new Error("本類不能直接實例化");
        }
    }
}

class Child extends Parent {
    constructor() {
        super(); // 正常
    }
}

new Child(); // ?
// new Parent(); // ? 拋出錯誤

3. 常見問題 (FAQ)

Q1:class 是一個新的數(shù)據(jù)類型嗎?

A: 不是。typeof Dog 返回的依然是 "function"。class 本質(zhì)上就是把函數(shù)包裝了一下,讓你覺得它是一個“類”。你可以把 class 看作是 functionprototype 的語法糖。

Q2:為什么在子類 constructor 里必須先寫 super()?

A: 這是 JS 的繼承機制決定的。子類實例的構(gòu)建是基于父類實例加工的,不先調(diào)用父類的構(gòu)造函數(shù)(生成父類 this),子類就沒有 this 可用。

Q3:什么時候該用繼承?

A: 雖然語法好看了,但設(shè)計原則依然建議 “多用組合,少用繼承”。如果你只是想復(fù)用一些工具方法,用普通對象或 Mixin 可能比繼承更靈活。只有在明確的“is-a”關(guān)系(如“狗是動物”)時才使用繼承。

4. 總結(jié)

JavaScript 的面向?qū)ο笳Z法終于進化到了主流水平:

  1. class:提供了標(biāo)準(zhǔn)的類定義寫法,雖然底層是原型,但代碼可讀性大幅提升。
  2. extends & super:讓繼承變得簡單直觀,不再需要手動操作 prototype 鏈。
  3. # 私有屬性:ES2022 提供了真正的訪問控制,封裝性不再是靠自覺。

最佳實踐建議:

在開發(fā) React 組件、Vue 類組件(Vue 2/3)或 Node.js 服務(wù)端類時,優(yōu)先使用 class 語法。對于敏感數(shù)據(jù)(如內(nèi)部狀態(tài)、API 密鑰),務(wù)必使用 # 私有屬性進行保護。

到此這篇關(guān)于JS面向?qū)ο笾畯膒rototype到class再到私有屬性的文章就介紹到這了,更多相關(guān)JS prototype到class再到私有屬性內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 微信小程序?qū)崿F(xiàn)滑動翻頁效果(完整代碼)

    微信小程序?qū)崿F(xiàn)滑動翻頁效果(完整代碼)

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)滑動翻頁效果,本文通過效果圖展示實例代碼講解的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • JavaScript實現(xiàn)簡易計算器小功能

    JavaScript實現(xiàn)簡易計算器小功能

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)簡易計算器小功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • 微信小程序scroll-view實現(xiàn)左右聯(lián)動

    微信小程序scroll-view實現(xiàn)左右聯(lián)動

    這篇文章主要為大家詳細介紹了微信小程序scroll-view實現(xiàn)左右聯(lián)動,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 微信小程序?qū)崿F(xiàn)頁面浮動導(dǎo)航

    微信小程序?qū)崿F(xiàn)頁面浮動導(dǎo)航

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)頁面浮動導(dǎo)航,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • Javascript 數(shù)組添加一個 indexOf 方法的實現(xiàn)代碼

    Javascript 數(shù)組添加一個 indexOf 方法的實現(xiàn)代碼

    Javascript 的字符串有個 indexOf 的方法,能夠返回字符在指定的字符串中的位置,非常有用,本文介紹了如何給 Javascript 數(shù)組也添加一個類似的方法。
    2009-09-09
  • JS實現(xiàn)一鍵復(fù)制

    JS實現(xiàn)一鍵復(fù)制

    這篇文章主要為大家詳細介紹了js實現(xiàn)點擊按鈕復(fù)制文本,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Bootstrap CSS組件之導(dǎo)航(nav)

    Bootstrap CSS組件之導(dǎo)航(nav)

    這篇文章主要為大家詳細介紹了Bootstrap CSS組件之導(dǎo)航(nav),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • jquery實現(xiàn)select下拉框美化特效代碼分享

    jquery實現(xiàn)select下拉框美化特效代碼分享

    這篇文章主要介紹了jquery實現(xiàn)select下拉框美化特效,實現(xiàn)效果簡潔大方,推薦給大家,有需要的小伙伴可以參考下。
    2015-08-08
  • JavaScript 語言的遞歸編程

    JavaScript 語言的遞歸編程

    關(guān)于遞歸的解釋見《SICP》第1章。下面是個簡單的遞歸編程題目。
    2010-05-05
  • JavaScript中new關(guān)鍵字的使用詳解

    JavaScript中new關(guān)鍵字的使用詳解

    在 JavaScript 中,new 關(guān)鍵字不僅是面向?qū)ο缶幊痰年P(guān)鍵要素,還是創(chuàng)建實例的重要手段,本文將深入探討 new 關(guān)鍵字的使用,理解它在對象創(chuàng)建和構(gòu)造函數(shù)調(diào)用中的作用,需要的朋友可以參考下
    2023-11-11

最新評論

娱乐| 友谊县| 慈利县| 剑阁县| 高要市| 天祝| 安宁市| 龙井市| 阜平县| 岳池县| 新津县| 六盘水市| 商都县| 大港区| 汉源县| 武冈市| 濮阳县| 蒙阴县| 梧州市| 安陆市| 巩义市| 刚察县| 鹿泉市| 巫山县| 曲周县| 绥阳县| 乌审旗| 临朐县| 兴海县| 涟水县| 乌审旗| 淮南市| 湘乡市| 准格尔旗| 海门市| 舞钢市| 南澳县| 黄山市| 缙云县| 鱼台县| 黑龙江省|