js中new的原理

面向對象

在了解new的原理之前,先簡單地了解一下構造函數和對象。

js可以通過構造函數創建對象:

function Test() {

}

var t = new Test();

構造函數的首字母大寫,以和普通函數區分開。

上述代碼中,Test被稱為「構造函數」 或者 「類」,Test是t的構造函數,t是Test的實例對象。

const a = {};

// 等價於
const a = new Object();

a的構造函數是Object(),這是js內置函數。

因此可以看出,所有的對象都是Object構造函數的實例。

那麼,在使用new關鍵字創建出一個實例對象的過程中,發生了什麼?

new的原理

在使用new關鍵字調用構造函數的時候,做了以下工作:

  • 1、創建了一個空的js對象
  • 2、將空對象的__proto__指向構造函數的prototype
  • 3、將this指向這個空的對象
  • 4、執行構造函數中的代碼,為空對象添加屬性和方法
  • 5、返回新的對象
function myNew(Class, ...args) {
    // 1.創建一個空對象
    let obj = {};

    // 2.將空對象的__proto__指向構造函數的prototype
    obj.__proto__ = Class.prototype;

    // 3.將this指向空對象
    // 4.執行構造函數中的代碼,為空對象添加屬性和方法(call方法會改變this的指向,並且自動執行)
    Class.call(obj, ...args);

    // 5.返回新的對象
    return obj;
}

function Test(name, age) {
    this.name = name;
    this.age = age;
}

var t = new Test('cxk', 22);
var tt = myNew(Test, 'cxk', 22);

console.log(t); // Test {name: 'cxk', age: 22}
console.log(tt); // Test {name: 'cxk', age: 22}

// 所有的對象都是Object構造函數的實例
console.log(t instanceof Object); // true
console.log(tt instanceof Object); // true