JavaScript:new關鍵字的執行過程

在使用JavaScript開發過程中,經常會用到new關鍵字,從字面意思來看,就是新建一個對象,那麼在我們看不見的數據之間的操作到底發生了什麼呢?使用new的這個過程執行了哪些操作?看下面的例子:

function Person(name) {
    this.name = name;
}
let zhangsan = new Person('張三');

上述代碼中new了一個Person,這其中的過程如下:

第一步:創建一個空對象object,let obj = new Object()---創建對象新對象,就是指在棧內新建了一個obj,這個obj實際上是指的堆中對應的一個地址。

第二步:設置原型鏈---這裏所說原型鏈,就是設置新建對象obj的隱式原型即_proto_屬性指向構造函數Person的顯示原型prototype對象,即

obj.proto = Person.prototype

第三步:改變構造函數Person的this綁定到新對象obj,並且利用call()或者是apply()來執行構造函數Person,如下:

let result = Person.call(obj)

第四步:將第三步中初始化完成後的對象地址,保存到新對象中,同時要判斷構造函數Person的返回值類型,爲什麼要判斷值類型呢?因爲如果構造函數中返回this或者是基本數據類型(number數值,string字符串,Boolean布爾,null,undefined)的值時,這個時候則返回新的實例對象,如果構造函數返回的值是引用類型的,則返回的值是引用類型,如下:

if (typeof (result) === "object") {
    func = result;
} else {
    func = obj; // 默認返回
}

這裏需要注意一點的就是JavaScript中的構造函數,是不需要返回值的,所以會默認返回一個新創建的空對象obj。

結合上面所說的new關鍵字執行過程,我們可以手寫一個函數實現一下,提升一下理解:

function newObject(func) {
    return function () {
        let newObj = {
            __proto__: func.prototype // 新生成一個對象,且新對象的隱式原型對象繼承自構造對象的顯示原型對象
        }
        var returnObj = func.call(obj, arguments) // 以第二次執行函數的參數,在obj作用域中執行func
        if ((typeof returnObj === "object" || typeof returnObj === "function") && returnObj !== null) {
            return returnObj;
        } // 同理,returnObj是 "對象" 類型,那麼這個對象會取代newObj作爲返回的對象
        return newObj
    }
}

 

有不足之處,希望各位大神指點指點。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章