1.{}、Object()、new Object()
我們平常工作中一般用let obj={}對(duì)象字面量的方法來(lái)創(chuàng)建對(duì)象.但其實(shí)創(chuàng)建對(duì)象還有一些其它方式,如:Object() new Object() Object.create().下面我們就來(lái)具體介紹這些方法的區(qū)別.
let test={a:1}
let test1=Object({a:1}) //不傳就是空對(duì)象{}
let test2=new Object({a:1}) //不傳就是空對(duì)象{}
我們打印三個(gè)結(jié)果

從圖中我們可以看出,三個(gè)結(jié)果一模一樣,并且原型都繼承了Object.prototype,我們總結(jié)下
- 通過(guò)字面量的方式和函數(shù)的方式都可以用來(lái)創(chuàng)建對(duì)象
- 當(dāng)以非構(gòu)造函數(shù)形式被調(diào)用時(shí)(也就是當(dāng)成函數(shù)執(zhí)行時(shí)),Object 的行為等同于 new Object()。參考mdn官網(wǎng)Object一節(jié). 簡(jiǎn)單來(lái)說(shuō), new Object()和Object()是一樣的,new可以省略
注意,上面我們調(diào)用Object時(shí)候傳遞的參數(shù)是個(gè)對(duì)象,現(xiàn)在我們傳遞其它類型的參數(shù)看看
let test3=new Object(1)
let test4=new Object("1")
let test5=new Object([1])
let test6=new Object(true)
打印4個(gè)結(jié)果


我們發(fā)現(xiàn),Object構(gòu)造函數(shù)會(huì)根據(jù)傳入的值的類型返回相應(yīng)的基本包裝類型的實(shí)例(對(duì)象包裝器),我們也可以給其進(jìn)行操作
let test3=new Object(1)
test3.a=2
console.log(test3 instanceof Number);//true
console.log(test3); //實(shí)例,引用類型
let a = Number(1);//這是轉(zhuǎn)型函數(shù),其它的還有String()、 Boolean()、 Array()
a.number=2 //不能操作,屬于基本數(shù)據(jù)類型
console.log(a); //所以結(jié)果為1
打印出的test3結(jié)果如下

注意:
上面我們說(shuō)了對(duì)象字面量、構(gòu)造函數(shù)創(chuàng)建對(duì)象,下面我們單獨(dú)來(lái)說(shuō)下Object.create(),因?yàn)樗容^特別.
2.Object.create()
mdn定義 : Object.create()方法創(chuàng)建一個(gè)新對(duì)象,使用現(xiàn)有的對(duì)象來(lái)提供新創(chuàng)建的對(duì)象的proto。
語(yǔ)法:
Object.create(proto,propertiesObject)
- proto:新創(chuàng)建對(duì)象的原型對(duì)象,必填
- propertiesObject:可選.參數(shù)和 Object.defineProperties() 的descriptor屬性描述符一樣.
返回結(jié)果:是一個(gè)新對(duì)象,帶著指定的原型對(duì)象和屬性
1.參數(shù)proto
如果不理解,我們直接看例子
var test1 = Object.create();
console.log(test1);
報(bào)錯(cuò):

提示參數(shù)必須只能為object或者null,大家可以試下,傳遞unedfined、數(shù)字啥的都會(huì)報(bào)同樣的錯(cuò)
繼續(xù)更改代碼,
let test1 = Object.create(null);
let test2={}
console.log(1,test1); //{} //無(wú)原型
console.log(2,test2); //{} 注意:雖然都為空對(duì)象,但是test2有原型
test1.a=1
console.log(3,test1); //{a:1}
console.log(4,test1.a); //1
console.log(test1 instanceof Object); //false
console.log(test2 instanceof Object); //true
打印結(jié)果

我們發(fā)現(xiàn),如果傳遞null,生成的對(duì)象,原型是空的,在該對(duì)象上沒(méi)有繼承 Object.prototype 原型鏈上的屬性或者方法,例如:toString(), hasOwnProperty()等方法
我們現(xiàn)在更改傳遞參數(shù),
let test1 = Object.create({a:1});
let test2={a:1}
console.log(1,test1); //{}
console.log(2,test2); //{a:1}
console.log(test1 instanceof Object); //true
console.log(test1.a); //1
console.log(test2 instanceof Object); //true
console.log(test2.a); //1
打印結(jié)果如下:

我們發(fā)現(xiàn),我們傳遞的對(duì)象被賦予到新生成對(duì)象的原型上.現(xiàn)在在回過(guò)頭來(lái)看定義,大家應(yīng)該就能理解了.所以
let test = {};
// 以字面量方式創(chuàng)建的空對(duì)象就相當(dāng)于:
let test = Object.create(Object.prototype);
console.log(test instanceof Object); //true
接下來(lái),我們看第二個(gè)參數(shù)
2.propertiesObject
我們上面講了,propertiesObject和Object.defineProperties的屬性描述符一致,現(xiàn)在舉個(gè)例子:
let test1 = Object.create({a:1},{
// a會(huì)成為所創(chuàng)建對(duì)象test1的屬性
b:{
value:1,
}
});
console.log(test1);

我們更改代碼
let test1 = Object.create({a:1},{
// a會(huì)成為所創(chuàng)建對(duì)象test1的屬性
b:{
value:1,
}
});
test1.a=2
test1.b=2
console.log(test1)

我們發(fā)現(xiàn),
我們無(wú)法更改b的值,因?yàn)槟J(rèn)writable為false,改為true即可
我們更改a的值,但是test1對(duì)象上面沒(méi)有a屬性,實(shí)際a屬性在原型上,所以相當(dāng)于新增,所以我們?nèi)绻?
test1.__proto__.a=2即可-
propertiesObject中定義的對(duì)象屬性才會(huì)適用于屬性描述符如writable等,原型上的屬性(即第一個(gè)參數(shù)里的屬性)不適用,所以我們可以進(jìn)行讀寫操作
let test1 = Object.create({a:1},{ // a會(huì)成為所創(chuàng)建對(duì)象test1的屬性 b:{ value:1, writable:true //其它參數(shù)和Object.defineProperties一樣,就不一一介紹了 } }); test1.b=2 console.log(test1)
