網上看了一些手動實現new操做符的方法和效果,如今來總結下app
function new1(func) { var newObj = Object.create(func.prototype); // 建立一個繼承自func.prototype的新對象 var returnObj = func.apply(newObj, Array.prototype.slice.call(arguments, 1)); //截取new1函數第二個以及第二個以後的參數,在newObj做用域內執行改造函數func if ((typeof returnObj === "object" || typeof returnObj === "function") && ret !== null) { return returnObj; } //若是傳入參數中的構造函數執行後的returnObj是「對象」類型(好比new1(Object)),那麼這個對象會取代newObj做爲返回的對象 return newObj; }
function new2(func) { return function() { let newObj = { __proto__: func.prototype // 新生成一個對象,且新對象的原型對象繼承自構造對象的原型對象 } var returnObj =func.apply(obj, arguments) // 以第二次執行函數的參數,在obj做用域中執行func if ((typeof returnObj === "object" || typeof returnObj === "function") && returnObj !== null) { return returnObj; } //同理,returnObj是「對象」類型(好比new1(Object)),那麼這個對象會取代newObj做爲返回的對象 return newObj } }
var object1 = new1(Object); var object2 = new2(Object)(); var object3 = new Object(); console.dir(object1) console.dir(object2) console.dir(object3)
在控制檯中查看結果函數
沒有區別。
再假定一個自定義的構造函數進行對比this
function person(name, age) { this.name = name this.age = age } var obj1 = new1(person,'zhus',25); var obj2 = new2(person)('zhus',25); var obj3 = new person('zhus',25); console.dir(obj1) console.dir(obj2) console.dir(obj3)
對比結果spa
也沒有區別。prototype