首先这篇文章是来自阮一峰大佬的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方法就能够。儿子没有方法去父亲身上找,这不就有点像面向对象了吗?
未完。。。