new和Object.create

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__指向構造函數,而後能夠實現繼承。

相關文章
相關標籤/搜索