new 運算符在平時開發中極少用到,可是全部人都知道,而Objext.create()方法就比較少知道了,我也是在學new過程的時候知道了這個方法。今天分享一下這兩個API,雖然本身仍是沒有很清楚。app
MDN上面寫着new關鍵字會進行以下操做:函數
建立一個空的簡單JavaScript對象(即{});this
連接該對象(即設置該對象的構造函數)到另外一個對象 ;spa
將步驟1新建立的對象做爲this的上下文 ;prototype
若是該函數沒有返回對象,則返回this。code
用代碼實現:cdn
function New(){對象
//建立一個空的簡單JavaScript對象(即{});繼承
let target = {};ip
//constructor是第一個參數,也就是構造函數,args是new的時候傳入的參數
let [constructor, ...args] = [...arguments];
//連接該對象(即設置該對象的構造函數)到另外一個對象 ;
target.proto = constructor.prototype;
//將步驟1新建立的對象做爲this的上下文 ;
let result = constructor.apply(target, args);
//若是該函數沒有返回對象,則返回this。
if(typeof result === "object" || typeof result === "function"){
return result
複製代碼
}
return target
}
function User(age, name) {}
var user = New(User, 18, 'wade')
其實早以前就說過,user是構造函數User的實例對象,user的隱式原型__proto__指向構造函數的顯式原型prototype。
Object.create()方法建立一個新對象,使用現有的對象來提供新建立的對象的__proto__。
function Fn() {}
Fn.prototype.te = 10;
var createObj = Object.create(Fn);
console.log(createObj.te);//undefined
console.log(createObj.prototype.te);//10
console.log(createObj.proto === Fn);//true
這樣看就很顯而易見了,這個方法會把原構造函數的屬性給丟失了,也就是說新建的對象createObj沒辦法直接使用構造函數的屬性。且原型鏈直接指向的是構造函數。
再看一段代碼:
var obj1 = {}
var obj2 = Object.create(null);
console.log(obj1);//{}有__proto__
console.log(obj2);//{}No properties
一樣是構造一個空的對象,使用Object.create構造出來的沒有繼承Object原型上的任何方法,沒必要擔憂會將原型鏈上的同名方法覆蓋掉。能夠當作一個很是乾淨的對象來使用。
Object.create還有第二個參數,爲新對象定義額外的屬性,指定的任何屬性都會覆蓋原型上的同名屬性:
var User = {
name:'kobe',
}
var user = Object.create(User,{
name:{
value:'wade'
複製代碼
}
});
console.log(user.name);//wade
其實我對Object.create的理解仍是有點不夠,如今理解的就是新建一個對象的隱式原型__proto__指向構造函數,而後能夠實現繼承。