看了這篇文章,能夠幫助你理解以下內容:javascript
一、向原型鏈上添加屬性爲何用prototype,而通常不用__proto__java
二、javascript爲何要設置一個函數對象,他的做用是什麼函數
三、更深層次瞭解原型鏈this
廢話很少說了,正文開始>>>spa
對象字面量建立的是對象,而構造函數建立的是函數對象。爲了幫助理解,我寫了一些代碼。prototype
以下兩段代碼,分別是使用對象字面量和構造函數建立對象。code
代碼段1:對象
var a={"name":"nihao"}; console.log(a);
代碼段2:blog
var a=function(name){ this.name=name; }; var b= new a("nihao"); console.log(b);
首先,咱們須要知道:繼承
一、函數對象的原型是對象(原型鏈爲:實例,經過new構造函數-->函數對象-->對象-->null)
二、函數有prototype屬性,而對象沒有
而後,在某些場景下,咱們有一個公共的屬性,須要多個新建的對象去繼承,這個時候就能體現出函數對象的特色了,咱們看下代碼:
一、使用構造器
var a=function(name){ this.name=name; }; a.prototype.sex="nan"; var b= new a("nihao"); console.log(b); console.log(b.name); console.log(b.sex); var c=new a("test"); console.log(c); console.log(c.name); console.log(c.sex);
如上,能夠很容易的實現屬性或方法的繼承,在控制檯打印上述代碼,能夠很容易看到原型鏈是這樣的(以對象b爲例):對象b-->函數對象-->對象-->null
二、使用對象字面量
使用對象字面量建立的是對象,他沒有prototype屬性,因此咱們只能經過__proto__,可是在對象上使用__proto__可能會致使一些問題的出現。代碼以下:
var a={"name":"nihao"}; a.__proto__.sex="nan"; console.log(a); console.log(a.name); console.log(a.sex); var b={}; console.log(b); console.log(b.name); console.log(b.sex);
如上,運行上面代碼,能夠很容易獲得運行結果:
{name: "nihao"} nihao nan {} undefined nan
哎,這個就很奇怪了,b對象明明設置的爲空啊?這是由於在執行a.__proto__.sex="nan";時候,程序向對象的原型上添加了一個屬性sex,而b是對象也是繼承的對象的原型,多以致使了這個問題的出現。
最後,總結下來就是:
函數對象是繼承自對象的原型,有了函數對象,咱們能夠給函數的原型添加屬性,這些屬性保存在函數對象中,可是又不會影響其餘對象。