爲啥要用new: 在javascript中, 經過new能夠產生原對象的一個實例對象,而這個實例對象繼承了原對象的屬性和方法。javascript
new操做符幹了什麼:java
new的過程當中遇到的坑一:bash
new Function
返回的是一個函數,
new Object
返回的是一個對象,那麼什麼是普通對象什麼是函數對象?
經過查找資料發現有這麼一句話:凡是經過 new Function()
建立的對象都是函數對象,其餘的都是普通對象。閉包
new的過程當中遇到的坑二:app
咱們看到new一個普通對象報錯,new一個函數對象才能夠,對於這個結果很好奇爲何?因而又查資料。函數
原型對象:ui
1).顯式原型: 每一個函數對象都有prototype屬性,稱爲顯式原型
2).隱式原型: 每一個普通對象都有_proto_屬性,指向的是相對應的構造函數的prototype,稱爲隱式原型
複製代碼
是否是能夠這麼理解,new一個普通對象,由於只有函數對象纔有prototype
屬性,因此普通對象沒法通new來建立一個新對象。只有經過函數對象來用new建立一個新的普通對象。this
分析上面步驟的具體內容:spa
__proto__
屬性,普通對象的__proto__
屬性指向他的構造函數(函數對象)的prototype
,因此a是b的構造函數,b是a的實例對象。具體實現步驟:prototype
function _new (fn) {
var obj = {
__proto__ : fn.prototype,
};
var res = fn.call(obj);
return Object.prototype.toString.call(res) === "[object Object]" ? res : obj;
}
複製代碼
咱們來運行一下代碼:
var o3 = new fun ('tom');
,並且若是構造函數包含好幾個屬性,在new的過程當中,有可能會傳入多個參數。 咱們須要改造一下:
function _new (fn) {
return function () { // 返回一個函數,調用此函數時傳入的參數達到new帶參數的目的。
var obj = {
__proto__ : fn.prototype,
};
var res = fn.apply(obj, arguments);
return Object.prototype.toString.call(res) === "[object Object]" ? res : obj;
}
}
複製代碼
咱們再來運行一下代碼:
固然使用閉包的方式會有內存泄漏的風險!因此咱們還能夠改造一下:
function _new () {
var fn = [].shift.call(arguments);
//var ags = [].prototype.slice.call(arguments, 1);
var obj = {
__proto__ : fn.prototype,
};
var res = fn.apply(obj, arguments);
return Object.prototype.toString.call(res) === "[object Object]" ? res : obj;
}
複製代碼