通俗理解:“類的原型對象就是一塊區域里有這個類的實例對象通用的屬性和方法”
?這就是 JavaScript 中原型(prototype)的核心作用和設計理念。??
??“一塊區域” = 原型對象本身(如?
String.prototype
,?Array.prototype
,?MyClass.prototype
):??- 這是一個實實在在存在的 JavaScript 對象。
- 它就是為特定“類”(或更準確地說,為通過特定構造函數創建的對象)專門開辟的共享資源池。
??“有...通用的屬性和方法” = 原型對象上定義的屬性和方法:??
- 開發人員(或語言本身)會將所有該類型對象需要共享的功能(方法)和可能需要的共享數據(屬性)放入這個“區域”中。
- 例如:
- 所有字符串都要會用?
.toUpperCase()
,?.slice()
?→ 這些方法就存在?String.prototype
?這個“區域”里。 - 所有數組都要會用?
.map()
,?.filter()
,?.push()
?→ 這些方法就存在?Array.prototype
?這個“區域”里。 - 你自己定義了一個?
Person
?類,所有?Person
?實例都要能?.sayHello()
?→ 這個方法就定義在?Person.prototype
?這個“區域”里。
- 所有字符串都要會用?
??“實例對象通用的” = 通過原型鏈實現共享:??
- 關鍵機制:當您通過?
new Constructor()
?創建一個實例(比如?const myStr = new String('hello');
?或?const p = new Person('Alice');
),這個新對象內部會自動連接(指向)構造函數的?prototype
?對象(那個“區域”)。 - ?當你訪問這個實例的屬性或方法時(如?
myStr.toUpperCase()
?或?p.sayHello()
):??- JavaScript 引擎會首先在實例對象自身屬性中查找。
- ?如果在實例自身沒找到,它會自動去您說的那個“共享區域”(即原型對象)里去查找!??
- 這個過程就是原型鏈查找。正是這個機制,使得所有實例都能復用定義在原型對象上的屬性和方法,實現了您所說的“通用”。
- 關鍵機制:當您通過?
1. 原型對象(Prototype Object)??
? 定義:
"原型對象是每個JavaScript函數自帶的prototype
屬性指向的特殊對象。它存儲了該構造函數創建的所有實例共享的屬性和方法。"
? 核心特點:
- 是構造函數(類)的共享方法容器
- 通過
構造函數.prototype
直接訪問 constructor
屬性指回構造函數本身
?2. 原型(Prototype)??
? 定義:
"原型是JavaScript中每個對象內部維護的隱式繼承鏈接?(通過__proto__
或Object.getPrototypeOf()
訪問)。它決定了屬性和方法的查找路徑。"
? 核心機制:
- 形成原型鏈(prototype chain)實現繼承
- 屬性查找規則:對象自身 → 原型鏈向上查找 → 終點
null
函數.prototype
是其實例的原型起點
原型對象和通過構造函數創建的實例對象
?相同點:
?都是對象(Object 類型)?
class MyClass {}
const a = new String("hello"); // a 是字符串對象
const protoObj = MyClass.prototype; // protoObj 是原型對象console.log(typeof a); // "object"
console.log(typeof protoObj); // "object"
?本質區別:
?特征? | ?普通對象 (如?a )?? | ?原型對象 (構造函數.prototype )?? |
---|---|---|
?創建方式? | new 構造函數() ?或字面量 | 函數聲明時自動創建 |
?核心作用? | 存儲數據/業務邏輯 | 作為共享方法的容器 |
?特殊屬性? | 無 | 必含?constructor ?指向構造函數 |
?內存中的角色? | 實例對象 | 其他對象的原型模板 |
?示例? | a.indexOf("e") ?(數據操作) | String.prototype.indexOf = function(){} ?(方法定義) |
?關鍵關系:
const str = new String("test");// 原型對象在繼承鏈的上游
console.log(str.__proto__ === String.prototype, // true:實例的隱式原型指向原型對象str instanceof String // true:繼承關系的體現
);// 原型對象本身也是普通對象
console.log(String.prototype instanceof Object // true:原型對象也是對象
);
總結:
"?原型對象是特殊的共享容器對象,普通對象是數據載體。
當執行?var a = new String()
:
a
?是實例對象?(用于操作數據)String.prototype
?是原型對象?(存儲所有字符串共享方法)
它們的共性是都是對象,差異在于在原型系統中的角色和定位不同。"
結論:
- 原型對象和實例對象都是對象,但原型對象是構造函數的屬性,實例對象是構造函數創建的對象。
- 它們通過原型鏈連接:實例對象的隱式原型(
__proto__
)指向構造函數的原型對象(prototype
)。