本篇文章帶給大家的內容是關於JavaScript如何模擬實作new關鍵字? (附代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
最近工作太忙,快接近兩週沒更新博客,總感覺有一些事情等著自己去做,雖然工作內容對自己提升挺大,但我總覺得,一直埋著頭走路,偶爾也需要抬起頭來,看看現在和自己的期望向是否脫軌,所以週末還是選擇來星巴克寫些文字。
今天記錄JavaScript 中new 關鍵字的模擬實現,當我們在模擬實現某個語言行為之前,應該想想這個行為都做了哪些事情,透過實踐,最後也能更加掌握知識點,這就是許多面試問題都會問到模擬實現的原因,目的是為了檢視候選人知識的深度。
function Person(name) { this.name = name; } var person = new Person('jayChou'); typeof(person) // "object" person instanceof Person // true person.__proto__ === Person.prototype // true person.constructor === Person // true person.constructor === Person.prototype.constructor // true
以上,可以看出:
new 建立並傳回了一個新對象,是建構函式的實例
物件的實例的建構子屬性其實是建構子的原型物件的constructor 屬性
物件實例的 __proto__ 關聯到建構函數的原型物件
#上面的內容有關於JavaScript 中原型物件和原型鏈的知識,不夠清楚的同學可以查看我之前的部落格。
由於 new 是 JS 的一個關鍵字,我們無法實作關鍵字,但我們可以透過函數的形式來模擬 new 關鍵字的行為。
知道 new 關鍵字做了哪些工作,那我們就有了模擬實作的基本想法。
/** * 模拟实现 JavaScript new 操作符 * @param {Function} constructor [构造函数] * @return {Object|Function|Regex|Date|Error} [返回结果] */ function mockNew() { // 创建一个空对象 let resultObj = new Object(); // 取传入的第一个参数,即构造函数,并删除第一个参数。 let constructor = Array.prototype.shift.call(arguments); // 类型判断,错误处理 if(typeof constructor !== "function") { throw("构造函数第一个参数应为函数"); } // 绑定 constructor 属性 resultObj.constructor = constructor; // 关联 __proto__ 到 constructor.prototype resultObj.__proto__ = constructor.prototype; // 将构造函数的 this 指向返回的对象 constructor.apply(resultObj, arguments); // 返回对象 return resultObj; } function Person(name) { this.name = name; } var person = mockNew(Person, "jayChou"); console.log(person); // constructor: ƒ Person(name) // name: "jayChou" // __proto__: Object
基本想法正確!所以我們完成了 new 關鍵字的初步模擬。夥伴們可以自己打一下,每句程式碼自己是否都能理解。
建構函數也是函數,有不同型別回傳值。有時候建構函數會傳回指定的物件內容,所以要對這部分進行處理。
/** * 模拟实现 JavaScript new 操作符 * @param {Function} constructor [构造函数] * @return {Object|Function|Regex|Date|Error} [返回结果] */ function mockNew() { // 创建一个空对象 let emptyObj = new Object(); // 取传入的第一个参数,即构造函数,并删除第一个参数。 // 关于为什么要用 Array.prototype.shift.call 的形式,见之前的博客文章 《JavaScript之arguments》 let constructor = Array.prototype.shift.call(arguments); // 类型判断,错误处理 if(typeof constructor !== "function") { throw("构造函数第一个参数应为函数"); } // 绑定 constructor 属性 emptyObj.constructor = constructor; // 关联 __proto__ 到 constructor.prototype emptyObj.__proto__ = constructor.prototype; // 将构造函数的 this 指向返回的对象 let resultObj = constructor.apply(emptyObj, arguments); // 返回类型判断, 如果是对象,则返回构造函数返回的对象 if (typeof resultObj === "object") { return resultObj } // 返回对象 return emptyObj; } function Person(name) { this.name = name; return { name: this.name, age: 40 } } var person = mockNew(Person, "jayChou"); console.log(person); // {name: "jayChou", age: 40} // age: 40 // name: "jayChou" // __proto__: Object
當傳回值傳回了一個自訂物件後,模擬 new 函數就會傳回該自訂物件。
JavaScript new 關鍵字的意義在於讓普通函數產生一個新對象,並將物件實例的 __proto__
關聯到函數的 prototype 物件。
本文有些地方需要一些前置知識,但是整體上理解是比較容易的。
#以上是JavaScript如何模擬實作new關鍵字? (附代碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!