首先這篇文章是來自阮一峯大佬的2010年的博客!!!!戳這裏javascript
我2010的時候還在談戀愛(逃)html
本身在學習到面向對象這裏有些疑惑,越學越糊塗,多是Java的副影響。。 : -(java
打算重頭梳理一下,而後看了這篇博客,以爲讀完了應該本身輸出一遍才能是本身的。bash
在JavaScript裏面對象是很常見,在這裏函數也成爲函數對象。可是這裏對象又不是真正的對象,它的語法中沒有Class(不涉及ES6的話),那麼封裝成對象應該怎麼去作呢?,下面就來具體說說:函數
咱們有兩隻貓,它有本身的顏色和名字:學習
var cat1 = {
name: 'po',
color: 'orange'
}
var cat2 = {
name: 'da',
color: 'white'
}
複製代碼
缺點很明顯,若是咱有上千只貓,那咱們就要累死了。因此就須要進行改進。ui
function Cat(name, color){
return {
'name': name,
'color': color
}
}
var cat1 = Cat('po', 'orange')
var cat2 = Cat('da', 'white')
複製代碼
這樣是否是就好看了許多,可是缺點是cat1和cat2沒有實質關聯,二者純粹是函數調用。這樣跟咱們的面向對象一點都不像。this
因爲以上的缺點就出現了構造函數的形式,以下:spa
function Cat(name, color){
this.name = name
this.color = color
}
var cat1 = new Cat('po', 'orange')
var cat2 = new Cat('da', 'white')
alert(cat1.name) //po
alert(cat2.name) //da
複製代碼
這樣一來就能夠將cat1和cat2創造了關聯,還使用了new來進行實例化。prototype
這時cat1和cat2會自動含有一個constructor屬性,指向它們的構造函數。
console.log(cat1.constructor === Cat) //true
console.log(cat2.constructor === Cat) //true
複製代碼
上面這段話是大佬原文中的話,可是我以爲這段話形成了誤導。因此從新說一下。上面兩段代碼爲true,沒錯。可是!!在cat1和cat2自己上是沒有constructor屬性,而是會去Cat.prototype上面去找,因此準確的來講應該是這樣的
console.log(Cat.prototype === Cat) //true
複製代碼
這裏順帶提一下new作了哪些事
var temp = {}
temp.__proto__ = Cat.prototype
Cat.call(temp)
return temp
複製代碼
看了new作的第二件事,就應該理解了爲何cat1和cat2自己沒有constructor。
這麼好的方法實現,爲何還要改進呢?
//若是我須要添加一個eat該怎麼寫呢?
function Cat(name, color){
this.name = name
this.color = color
this.eat = function(){ console.log('eaaaaaaaaaaaaat') }
}
var cat1 = new Cat('po', 'orange')
var cat2 = new Cat('da', 'white')
console.log(cat1.eat) //eaaaaaaaaaaaaat
console.log(cat2.eat) //eaaaaaaaaaaaaat
console.log(cat1.eat === cat2.eat) //false
複製代碼
看上面,確實是實現了eat的方法,可是這個方法對應的不是同一塊內存,這是爲何呢?由於咱們new幹了這件壞事,new中每次都是建立了一個空對象。
怎麼改進上面的問題呢?
Cat.prototype.eat = function(){ console.log('eaaaaaaaaaaaaat') }
cat1.eat() //eaaaaaaaaaaaaat
cat2.eat() //eaaaaaaaaaaaaat
console.log(cat1.eat === cat2.eat) //true
複製代碼
對,直接在構造函數的原型上面去找eat方法就能夠。兒子沒有方法去父親身上找,這不就有點像面向對象了嗎?
未完。。。