js/ts prototype最簡單且深刻的理解

abc126655發表於2024-06-23

最關健的二點:
1. js任何物件(函式也是物件)都有__proto__私有屬性,有的可能會顯示[[Prototype]] (chorme瀏覽器),程式碼直接訪問屬性會報錯,但可以正常執行的。__proto__只是另一個物件的引用(一般是型別物件,也可以修改)。
2. 只有函式物件Function才有 .prototype屬性,它本身就是一個物件,給其它物件提供共享屬性和方法的物件。是可以正常訪問,每個prototype物件都有constructor屬性,它是建構函式的引用。

補充: 所有內建型別是一個Function物件,因此可以修改Number.prototype( TypeScript 不允許直接擴充套件原生型別,可以使用型別守衛或型別斷言來規避 TypeScript 的型別檢查,但這種做法需要謹慎考慮)

透過下面例子來解釋上面二名話:
class A{};
定義了A類,其實定義了二個型別: A型別和 typeof(A)型別(A.prototype.constructor的型別)。就和內建型別number與Number,string與String是一樣的。
const a:typeof A = A; // typeof A 可以是A或者A的子類
const b:A = new A(); // b是呼叫了constructor才生成的物件
為什麼會這樣?js原本是沒有class定義的,是透過函式和prototype物件來實現其它語言類的功能(其它語言定義一個類後,只有一個型別),所以
A.proto = Function.prototype;
b.proto = A.prototype;
prototype屬性,它本身就是一個物件,所以
Function.prototype.proto = Object.prototype
A.prototype.proto = Object.prototype
Object.prototype.proto = null

再看一個例子
const aa:number =1;
aa.proto = Number.prototype; Number.prototype.proto =Object.prototype;
Number.proto = Function.protoype; Function.protoype.proto = Object.prototype;
內建型別也是和自定義型別一樣的

好像真的就是二句話就說清楚了prototype,如果有理解錯誤的地方歡迎討論指正。

相關文章