一、創建對象的方法
閱讀犀牛書(《javascript權威指南》),書中將js創建對象的方法分為四種,對象字面量、構造函數、原型、Object.create()。
1、對象字面量:
需要修改屬性只能在對象上修改
var t1 = {x: 1};//也可以寫作var t1 = new Object({x: 1});
2、構造函數
需要修改屬性也只能在對象上修改,在對象上的修改不會影響到構造器
function f2(){
this.x = 1;
};
var t2 = new f2();//t2創建后,t2的屬性不受f2的影響
3、原型
可以通過修改構造器prototype
的值,修改對象的值,但是如果對象上的屬性重新賦值了,則在對象上獲取的值是重新賦值的值,而不是構造器prototype
的值
function f3(){};
var t3 = new f3();
f3.prototype.x = 1;//如果重新給f3.prototype.x賦值,t3.x也會隨之改變
t3.x = 3; //改t3的值重新賦值之后t3.x不會隨f3.prototype.x改變
4、Object.create()
可以通過修改父對象的值修改對象的值,重新賦值則無法修改
var f4 = {x: 1};
var t4 = Object.create(f4);//如果f4的屬性改變,t4相應的屬性也會改變
二、創建的對象的本質
以上四種方法看似不同,但他們的本質是一樣的,都是通過最基本的new Object()
與原型來實現對象的創建的。
使用構造器創建對象,其本質如下:
new函數說明.png
對象的
__proto__
指向了構造器的prototype
,所以修改構造器的屬性不會影響對象,但是修改構造器原型會。使用
Object.create()
:
Object.create說明.png
對象的
__proto__
指向了構造器,所以可以通過修改父對象影響對象的屬性
三、__proto__
與prototype
__proto__
和prototype
是比較容易混淆的兩個屬性。__proto__
是對象的屬性,用來在原型鏈上查找你需要的方法的實際對象。prototype
是函數獨有的屬性當我們使用關鍵詞new
并且將函數作為構造函數來構造對象的時候, 它被用來構建對象的__proto__
屬性.
對于非函數的對象來說比較簡單只有__proto__
,但是函數也是對象,所以在函數中__proto__
和prototype
同時存在,一個函數作為構造器時,參與其中的是prototype
屬性,但是被創建時,__proto__
指向了Function.prototype
。