請說下你對__proto__和prototype的理解

王铁柱6發表於2024-11-23

在 JavaScript 中,__proto__prototype 是兩個容易混淆但又至關重要的概念,它們都與原型鏈相關,但扮演著不同的角色。理解它們的區別對於理解 JavaScript 的繼承機制至關重要。

prototype (原型物件)

  • 定義: prototype 屬性是函式物件才擁有的屬性。它指向一個物件,這個物件就是透過該函式建立的例項的原型。換句話說,當使用 new 運算子建立一個新的物件時,新物件的 __proto__ 屬性會指向建構函式的 prototype 屬性。
  • 作用: prototype 屬性用於定義透過建構函式建立的物件的共享屬性和方法。所有透過該建構函式建立的例項都共享同一個原型物件。這樣可以節省記憶體,並且方便地實現繼承。
  • 例子:
function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log("Hello, my name is " + this.name);
};

const person1 = new Person("Alice");
const person2 = new Person("Bob");

person1.greet(); // Output: Hello, my name is Alice
person2.greet(); // Output: Hello, my name is Bob

console.log(person1.greet === person2.greet); // Output: true (Both instances share the same greet function)

__proto__ (原型鏈指標)

  • 定義: __proto__ 屬性是所有物件都擁有的屬性 (除了透過 Object.create(null) 建立的物件)。它是一個內部屬性,指向建立該物件的建構函式的 prototype 屬性。換句話說,它指向該物件的原型。
  • 作用: __proto__ 屬性構成了 JavaScript 的原型鏈。當訪問一個物件的屬性時,JavaScript 引擎首先會在物件自身查詢該屬性。如果找不到,就會沿著 __proto__ 指向的原型物件繼續查詢,直到找到該屬性或者到達原型鏈的頂端 (null)。
  • 例子: 在上面的例子中,person1.__proto__ 指向 Person.prototype

關鍵區別總結:

特性 prototype __proto__
歸屬 函式物件 所有物件 (除Object.create(null)建立的物件)
作用 定義例項的原型 指向物件的原型
訪問方式 直接訪問 透過 Object.getPrototypeOf(obj) 或非標準的 obj.__proto__ 訪問

Object.getPrototypeOf()

推薦使用 Object.getPrototypeOf(obj) 來獲取物件的原型,因為它比 __proto__ 更標準和更可靠。 __proto__ 雖然在大多數現代瀏覽器中都受支援,但它並不是 ECMAScript 標準的一部分,並且在某些環境中可能不可用。

最佳實踐:

為了程式碼的可讀性和可維護性,建議使用現代 JavaScript 的 class 語法來定義類和繼承關係,它底層仍然是基於原型鏈的,但提供了更清晰的語法。

希望這個解釋能夠幫助你理解 __proto__prototype 的區別。

相關文章