動態

詳情 返回 返回

5分鐘內理解 .prototype 鏈 | 2024 - 動態 詳情

  • CSS技巧與案例詳解
  • vue2與vue3技巧合集
  • VueUse源碼解讀

image.png

在JavaScript的世界裏,原型(prototype)系統是一個常被討論但不易掌握的概念。作為JavaScript繼承模型的基石,理解原型對於構建大型應用或進行對象操作至關重要。讓我們一起探索這個迷人的話題,揭開原型系統的神秘面紗。

什麼是原型?

在JavaScript中,每個對象都有一個內部屬性[[Prototype]]。這個屬性指向另一個對象,我們稱之為原型。原型就像一個模板,對象從中繼承屬性和方法。

當我們嘗試訪問一個對象的屬性或方法時,JavaScript首先在對象本身查找。如果沒有找到,它會沿着原型鏈向上查找,直到找到該屬性或達到原型鏈的頂端(null)。

我們通過一個簡單的例子來理解這個過程:

const animal = {
  makeSound: function() {
    console.log("Some generic animal sound");
  }
};

const dog = Object.create(animal);
dog.bark = function() {
  console.log("Woof!");
};

dog.makeSound(); // 輸出: "Some generic animal sound"
dog.bark();      // 輸出: "Woof!"

在這個例子中,dog對象繼承了animalmakeSound方法,同時擁有自己的bark方法。

創建對象與原型

我們深入瞭解對象創建時原型是如何鏈接的:

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, I'm ${this.name}`);
};

const alice = new Person("Alice");
alice.greet(); // 輸出: "Hello, I'm Alice"

這裏發生了什麼?

  1. Person是一個構造函數。
  2. 當我們使用new關鍵字創建Person的實例時,JavaScript創建了一個新對象(alice),並將其[[Prototype]]鏈接到Person.prototype
  3. 當調用alice.greet()時,JavaScript首先在alice對象上查找greet方法。沒有找到,所以它沿着原型鏈查找,在Person.prototype上找到並執行了這個方法。

原型鏈與繼承

JavaScript通過原型實現繼承。與傳統的類繼承不同,JavaScript對象直接從其他對象繼承。這被稱為"原型繼承"。讓我們擴展前面的例子來演示繼承:

function Developer(name, language) {
  Person.call(this, name);
  this.language = language;
}

Developer.prototype = Object.create(Person.prototype);
Developer.prototype.constructor = Developer;

Developer.prototype.code = function() {
  console.log(`${this.name} is coding in ${this.language}`);
};

const bob = new Developer("Bob", "JavaScript");
bob.greet(); // 輸出: "Hello, I'm Bob"
bob.code();  // 輸出: "Bob is coding in JavaScript"

在這個例子中:

  1. 我們使用Object.create(Person.prototype)創建了Developer.prototype,確保Developer實例繼承自Person.prototype
  2. 我們重置了Developer.prototype.constructor,使其指向Developer函數。
  3. bob現在可以訪問從Person.prototype繼承的greet方法和定義在Developer.prototype上的code方法。

原型方法與屬性遮蔽

當直接在對象上添加一個屬性或方法時,它會遮蔽原型鏈中同名的屬性或方法:

bob.greet = function() {
  console.log("Hi, I'm a developer!");
};

bob.greet(); // 輸出: "Hi, I'm a developer!"

在這個例子中,直接定義在bob上的greet方法覆蓋了從Person.prototype繼承的方法。

修改原型的風險

雖然可以修改內置原型如Array.prototypeObject.prototype,但這通常是不推薦的做法。這可能導致不可預知的行為和與其他代碼的衝突。

結語

JavaScript的原型系統雖然初看複雜,但掌握它能讓我們更深入地理解JavaScript的工作原理。儘管在使用現代JavaScript和TypeScript的項目中,我們很少直接操作原型,但理解原型對於調試和優化應用程序仍然至關重要。

通過深入理解原型,我們能夠編寫更高效、更靈活的JavaScript代碼,為構建強大的前端應用奠定堅實基礎。

首發於公眾號 大遷世界,歡迎關注。📝 每週一篇實用的前端文章 🛠️ 分享值得關注的開發工具 ❓ 有疑問?我來回答

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

user avatar tianmiaogongzuoshi_5ca47d59bef41 頭像 grewer 頭像 cyzf 頭像 Leesz 頭像 freeman_tian 頭像 aqiongbei 頭像 hard_heart_603dd717240e2 頭像 shuirong1997 頭像 zhulongxu 頭像 wmbuke 頭像 kitty-38 頭像 romanticcrystal 頭像
點贊 81 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.