手動實現一個new操做

寫在前面


在全部的前端面試中經常喜歡考面試者如何手寫一個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操做符大概作了幾件事情:面試

  1. 返回(產生)了一個新的對象
  2. 訪問到了類Otaku構造函數裏的屬性
  3. 訪問到Otaku原型上的屬性和方法 而且設置了this的指向(指向新生成的實例對象)

經過上面的分析展現,能夠知道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; // 返回實例
}
相關文章
相關標籤/搜索