new一個對象的詳細過程,手動實現一個 new操作符


可以描述 new一個對象的詳細過程,手動實現一個 new操作符

1. new 一個對象的詳細過程:(原文地址

首先我們看下new Person輸出什么?

var Person = function(name, age) {
        this.name = name;
        this.age = age;
    };
    Person.prototype.show = function() {
        console.log(this.name, this.age);
    };
    var p = new Person("bella", 10);
    console.log(p);

 

 有屬性name, age 和 __proto__

__proto__里面有原型方法show,constructor, __proto__

然后我們再輸出構造器Person.prototype:

對比一下,發現p的__proto__的值就是構造函數Person的prototype的屬性值。

因此new操作符創建對象可以分為以下四個步驟

  ① 創建一個空對象;

  ② 鏈接到原型(將所創建對象的__proto__屬性值設為構造函數的prototype屬性值);

  ③ 綁定this(構造函數中的this指向新對象並且調用構造函數);

  ④ 返回新對象。

因此上面的過程就可以等同於下面的過程:

var Person = function(name, age) {
    this.name = name;
    this.age = age;
};
Person.prototype.show = function() {
    console.log(this.name, this.age);
};
// var p = new Person("bella", 10);
var p = {};
p.__proto__ = Person.prototype;
Person.call(p, "balle", 10);
console.log(p);

2. 手動實現一個new操作符:(原文地址

要手動實現 new 操作符,就要明白new操作符做了什么事,如 上面 總結的new操作符創建對象的四個步驟。

這樣我們就可以實現一個new方法了:

function realizeNew () {
    //創建一個新對象
    let obj  = {};
    //獲得構造函數
    let Con = [].shift.call(arguments);
    //鏈接到原型(給obj這個新生對象的原型指向它的構造函數的原型)
    obj.__proto__ = Con.prototype;
    //綁定this
    let result = Con.apply(obj,arguments);
    //確保new出來的是一個對象
    return typeof result === "object" ? result : obj
}

[].shift.call(arguments)的作用是將調用realizeNew方法的第一個值拿出來:

我們實現的realizeNew()需要傳入的參數是:構造函數 + 屬性

首先創建一個新對象,

然后通過 arguments 類數組我們可以知道參數中包含了構造函數以及我們調用create時傳入的其他參數,接下來就是要想如何得到其中這個構造函數和其他參數,由於arguments是類數組,沒有直接的方法可以供其使用,我們可以有以下兩種方法:

  1)Array.form(arguments).shift();轉換成數組,使用數組方法shift將第一項彈出

  2)[].shift().call(arguments);通過call()讓arguments能夠借用shift()方法

綁定this的時候需要注意:

  1)給構造函數傳入屬性,注意構造函數的this屬性;

  2)參數傳進Con對obj的屬性復制,this要指向obj對象;

  3)在Con內部手動指定函數執行時的this使用call、apply實現

最后需要返回一個對象

測試:

function Person (name,age){
    this.name = name;
    this.age = age;
    this.say = function () {
        console.log("I am " + this.name)
    }
}
 
//通過new創建構造實例
let person1 = new Person("Curry",18);
console.log(person1.name);      //"Curry"
console.log(person1.age);       //18
person1.say();      //"I am Curry'
 
//通過realize()方法創造實例
let person2 = realizeNew (Person,"Curry",18);
console.log(person2.name);      //"Curry"
console.log(person2.age);       //18
person2.say();      //"I am Curry'


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM