JS中new的實現原理及重寫

2021-10-08 21:19:23 字數 2430 閱讀 9707

提到new,肯定會和類和例項聯絡起來,如:

function

func()

let f = new func();

上面的**,我們首先建立了乙個函式,如果是用物件導向的說法就是建立了乙個function類的例項,如果直接執行這個函式,那它就是乙個普通的函式,如果用new執行,則這個函式被稱為乙個自定義的類。

如果是乙個普通函式執行,他會如下做幾件事:

·形成乙個全新的執行上下文ec(execution context 執行環境)

·形成乙個ao(activation object 活動物件)變數物件,初始化arguments和形參賦值

·初始化作用域鏈

·**執行

如果是new函式執行,它既有普通函式執行的一面,也有自己獨有的東西:

·預設建立乙個物件,而這個物件就是當前類的例項

·宣告其this指向,讓其指向這個新建立的例項

·不論其是否寫return,都會把新建立的例項返回,這裡有個特殊點,如果使用者自己返回內容,且返回的是乙個引用型別值,則會把預設返回的例項給覆蓋掉,此時返回的值就不再是類的例項了

console.log(f);  //

=>

//f是func這個類的例項

//相當於給建立的例項物件新增乙個num的屬性 obj.num=200 (因為具備普通函式執行的一面,所以只有this.***=***才和建立的例項有關係,此案例中的x只是ao中的私有變數)

console.log(f

instanceof func); //

=>true instanceof用來檢測某乙個例項是否屬於這個類

每一次new出來的都是乙個新的例項物件

console.log(f === f2); //

=>false

既然知道了new都做了什麼事情,我們重新一下new:

/*

* 內建new的實現原理

* @params

* func:操作的那個類

* args:new類的時候傳遞的實參集合

* @return

* 例項或者自己返回的物件 */

function

_new(func, ...args) ;

//也會把類當做普通函式執行

//執行的時候要保證函式中的this指向建立的例項

let result =func.call(obj, ...args);

//若客戶自己返回引用值,則以自己返回的為主,否則返回建立的例項

if ((result !== null && typeof result === "object") || (typeof result === "function"))

return

obj;

}

我們試一下:

let f3 =_new(func);

console.log(f3);

//=>

我們繼續測試:

func.prototype.log = function

() let f4 =_new(func);

f4.log();

//=>uncaught typeerror: f4.log is not a function

也就是說,func原型上的方法其實例沒法呼叫,我們還需要修改:

/*

* 內建new的實現原理

* @params

* func:操作的那個類

* args:new類的時候傳遞的實參集合

* @return

* 例項或者自己返回的物件 */

function

_new(func, ...args) ;

let obj =object.create(func.prototype);

//也會把類當做普通函式執行

//執行的時候要保證函式中的this指向建立的例項

let result =func.call(obj, ...args);

//若客戶自己返回引用值,則以自己返回的為主,否則返回建立的例項

if ((result !== null && typeof result === "object") || (typeof result === "function"))

return

obj;

}

這樣應該就可以了。

let f6 =_new(func);

f6.log();

//=>ok

js中new的原理與實現

這裡使用es6的結構來獲取建構函式所需的引數 也可以使用arguments來獲取,不過es6中不這麼建議了,要用的話進行arguments 0 的提取與裁剪就可以了 function new fn,args 構造空物件 fn.obj,args 建構函式賦值與this指向的修改 obj.proto f...

new的原理及實現

new運算的過程 1 建立乙個空物件 3 繫結 this 將物件作為建構函式的 this 傳進去,並執行該建構函式 4 返回新物件 如果建構函式返回的是乙個物件,則返回該物件 否則 若沒有返回值或者返回基本型別 返回第一步中新建立的物件 var person function name person...

new 原理及模擬實現

new 運算子建立乙個使用者定義的物件型別的例項或具有建構函式的內建物件的例項。舉個栗子 function car color car.prototype.start function var car new car black car.color 訪問建構函式裡的屬性 black car.star...