前言
在JavaScript中, 當我們使用new
關鍵字呼叫一個建構函式時,JavaScript會執行一系列隱式的步驟來建立並初始化一個新物件。具體來說,這個過程包括:
1. 建立空物件 2. 繫結`this` 3. 屬性與方法初始化 4. 原型鏈連線 5. 返回物件
手寫myNew函式
理解了new
操作的內部機制後,我們可以嘗試手動模擬這一過程。下面的myNew
函式就是這樣一個嘗試:
function myNew(Fun, ...args) { let obj = {}; // 建立空物件 Fun.apply(obj, args); // 呼叫建構函式,繫結this到obj,傳遞引數 obj.__proto__ = Fun.prototype; // 設定原型鏈 return obj; // 返回新物件 }
這段程式碼清晰地展示了建立例項的每一步,從建立空物件、繫結建構函式的上下文,到設定原型鏈,最後返回新物件,完全復現了new
運算子的功能。
物件導向的核心概念
let obj={ name:'鴨王' } let obj2 ={ name:'鴨王2', getName:function(){ console.log('///////////////////////') console.log(this.name) } } let obj3={} //obj3是原型物件,查詢obj2的屬性 obj3.__proto__=obj2 console.log(obj3.name) obj3.__proto__=obj console.log(obj3.name)
建構函式:如
Duck
或Person
,用於初始化物件的屬性和行為。原型物件(prototype):每個建構函式都有一個關聯的原型物件,用於存放所有例項共享的方法。如
Duck.prototype.singing
和Person.prototype.sayHello
。原型鏈:透過
__proto__
屬性,每個物件可以連結到其建構函式的原型物件,形成一條原型鏈,從而實現繼承和方法查詢機制。
例項與原型的互動
透過myNew
建立的duck
例項,能夠訪問到Duck.prototype
上的singing
和fly
方法,這是因為JavaScript引擎在查詢一個物件的屬性或方法時,如果在物件自身找不到,就會沿著原型鏈向上查詢,直到找到為止或到達原型鏈的末端(通常是Object.prototype
)。
總結
JavaScript的物件導向模型以其獨特的原型鏈繼承方式,提供了靈活而強大的物件建立與複用機制。透過深入理解new
運算子的工作原理及手動實現類似功能的myNew
函式,我們可以更加透徹地掌握JavaScript中物件導向程式設計的核心概念。這種機制不僅讓每個物件擁有自己獨特的屬性,同時透過共享原型上的方法實現了高效程式碼複用,是JavaScript強大表現力和靈活性的一個重要體現。