在全部的前端面試中經常喜歡考面試者如何手寫一個new操做符,做爲在準備秋招的大三黨,我也要考慮這些。
那麼咱們先看看new操做符都幹了什麼事情,有哪些操做?經過下面的代碼來進行思考:前端
// 新建一個類(構造函數) function Otaku(name, age) { this.name = name; this.age = age; // 自身的屬性 this.habit = 'pk'; } // 給類的原型上添加屬性和方法 Otaku.prototype.strength = 60; Otaku.prototype.sayYourName = function () { console.log('I am ' + this.name); } // 實例化一個person對象 const person = new Otaku('喬峯',5000); person.sayYourName(); console.log(person);//打印出構造出來的實例
從控制檯打印出來的結果咱們能夠看出new操做符大概作了幾件事情:面試
經過上面的分析展現,能夠知道new團伙裏面必定有Object的參與,否則對象的產生就有點說不清了。 先來邊寫寫:數組
// 須要返回一個對象 藉助函數來實現new操做 // 傳入須要的參數: 類 + 屬性 const person = new Otaku('喬峯',5000); const person1 = objectFactory(Otaku, '鳩摩智', 5000); // 開始來實現objectFactory 方法 function objectFactory(obj, name, age) {} // 這種方法將自身寫死了 如此他只能構造以obj爲原型,而且只有name 和 age 屬性的 obj // 在js中 函數由於arguments 使得函數參數的寫法異常靈活,在函數內部能夠經過arguments來得到函數的參數 function objectFactory() { console.log(arguements); //{ '0': [Function: Otaku], '1': '鳩摩智', '2': 5000 } // 經過arguments類數組打印出的結果,咱們能夠看到其中包含了構造函數以及咱們調用objectfactory時傳入的其餘參數 // 接下來就是要想如何獲得其中這個構造函數和其餘的參數 // 因爲arguments是類數組,沒有直接的方法能夠供其使用,咱們能夠有如下兩種方法: // 1. Array.from(arguments).shift(); //轉換成數組 使用數組的方法shift將第一項彈出 // 2.[].shift().call(arguments); // 經過call() 讓arguments可以借用shift方法 const Constructor = [].shift.call(arguments); const args = arguments; // 新建一個空對象 純潔無邪 let obj = new Object(); // 接下來的想法 給obj這個新生對象的原型指向它的構造函數的原型 // 給構造函數傳入屬性,注意:構造函數的this屬性 // 參數傳進Constructor對obj的屬性賦值,this要指向obj對象 // 在Coustructor內部手動指定函數執行時的this 使用call、apply實現 Constructor.call(obj,...args); return obj; }
function objectFactory() { let Constructor = [].shift.call(arguments); const obj = new Object(); obj.__proto__ = Conctructor.prototype; Constructor.call(obj,...arguments); return obj; }
function myNew(Obj,...args){ var obj = Object.create(Obj.prototype);//使用指定的原型對象及其屬性去建立一個新的對象 Obj.apply(obj,args); // 綁定 this 到obj, 設置 obj 的屬性 return obj; // 返回實例 }