如果理解不了什么是面向对象,那有什么必要去理解?也许换个角度想想,我们理解了面向对象能干吗?
“javascript面向对象”,“什么是javascript面向对象”,“什么是prototype和__proto__”,“什么是Object和Function”...........等等诸如这一系列问题。
我相信你不止一次在百度搜索这些关键字,而且确信你点开一个搜索内容看的前几句一般都是诸如此类的解释:
“函数才有prototype对象有__proto__”
“对象:对象是一个整体,对外提供一些操作”
“面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,ECMAScript 没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。”。。。。。
.........................................我更相信你看了一篇博文前面几句然后又点开下一篇博文如此反复
接着就抽根烟开始怀疑人生,“难道我学不会javascript”
当你点开这篇文章的时候,你应该还是没有理解,我相信你是花了很多时间才找到的,因为我的博客不出名,
既然如此累还是搞不懂我们和不妨静下心来,休息一会,拉会家常,
生活,没必要把自己搞得那么狼狈不堪,那么累
正文
在开始摆龙门阵之前,我要求你放下面向对象,就当不存在这个概念。因为面向对象本来就是一种描述抽象事物的形容词叫法。重要的事情说三遍,"放下面向对象",反正你都不理解那要他何用?(你叫猫的名字它不过来,那为什么要给他取名字勒?)
第一步:(预备知识)
1:首先你应该具备基础知识(相信你看到这篇博客应该是具备了)
2:其次你应该对对象为什么"引用类型"有一个比较抽象的理解(比如能用生活当中的例子举例)
3:对函数的属性和作用于以及this有那么一点深入了解,知道什么是上下文会更好(一会用的不多),prototype和__proto__知道就行,主要就是扯他们
第二步(我们从一个故事开始入手)
"万物都有根,一切皆无形"(讲一个中国传统的故事:女娲造人应该知道吧,创世女神女娲化生万物 [1] ,每天至少能创造出七十样东西 [2] ,开世造物,因此被称为大地之母[3-6] 。她是古老相传的大母神。相传女娲以泥土仿照自己抟土造人,创造并构建人类社会;又替人类立下了婚姻制度,使青年两性相互婚配,繁衍后代,因此也被传为主职姻缘与情爱的皋禖古神。)
?那么问题来了:女娲是谁造的?
你要是解释清楚了那我们就无话可说了,但如果我们要是解释不清楚怎么办?
答案:凉拌,既然解释不清楚那我们何不把他当真相去对待?不过我们可以试图去寻找真相
Object()是什么?
function fun(){......} function Person(){......}
Object()和fun()以及Person()他们其实就是一个函数
function Object(){......}//调用函数就要写成Object()
但是为什么我们直接打开编辑器什么都不写直接console.log(Object())或者浏览器控制台直接Object()会创建一个对象,那为什么console.log(fun())就报错勒;--》那是不是说明javascript本身就有Object这个函数,而没有fun--》这就是内置构造函数
那什么是--------构造函数?
我们从文字表面来理解"构造"两个字(注意,不包含“函数两个字”):比如我需要一件衣服,那么我是不是要去商店买一件衣服。那么我现在需要生产衣服,那你是不是的建一个生产衣服的工厂啊?当然,你也可以手工一件一件的做,工厂做一百件你同样能做一百件。
(先不说卖衣服)我生产一件衣服的情况就好比我需要一个对象
var obj = {
name:"adidashi",
color:"red",
temperature:function(){........}
}
那如果我要生产10件怎么办,(有的妇女确实能织出十件甚至更多),那我要生产100件,1000件怎么办呢?难道你要写一百个一千个对象?,显然都是一样的衣服一样重复的代码
那么只有建立工厂,(就比如说你真的要生产衣服(大规模的)在现实生活当中你也必须要建立工厂)
如何创建工厂:
首先得选地方,那么我们就用函数吧?
接着工厂造好了,是不是得有那么一个模板,就比如街上那种小蛋糕,他是用模板一次可以做很多个,如果用手捏一次只能捏一个,制衣厂那种流水线
模板:对于模板生产出来的东西就只有一个有共同点,"都是一样的"。同一个批次的衣服品牌一样把,大小一样把,颜色一样把...................
//,工厂建好了我们是不是需要对原料进行加工,然后出厂
第一步:原料(就是一个空对象)
var obj={}
第二步:我们需要对原料加工
obj .name="adidas"
obj .color="red"
obj .temperature=function(){.........}
第三步:出厂
return obj;
}
出厂的目的就是让别人来买啊,假设有两个人来买,
var person1=GarmentFactory( );
var person2= GarmentFactory( );
弊端:如果所有对象name的值不一样要去改函数源代码或者对象自己本身(person1),那样应该很麻烦吧,那么为什么我们不可以通过参数赋值呢?后面会解决的
这两个人如果要买衣服那么就是说他们必须要历经造一个工厂(重复调用函数,这是性能问题了),买原料,出厂,其实说白了,就是对象字面量的简写,"但是我们的这个工厂的确是模板的一个完美解释"与其写十个字面量一样的对象,不如用函数吧把他们的共同点装在一起,需要衣服就去调用一函数。
那么问题又来了?
为什么我要买一件衣服,就要去建一个工厂,买十件衣服就要建十个工厂(相当于在计算机内存开辟十个存储空间然后又不要这十个空间如此反复),明明都是一样的衣服,很显然这是没必要的,那么我们如何做到只需要一个工厂而做到不需要每次买衣服就建工厂勒?
new:我们需要一个代理人,和工厂联系!!!
new(官网有解释):运算符,任何函数都可以new,用来初始化对象的,一旦通过new调用的函数就叫构造函数,(你自己开工厂造衣服你叫老板,而你通过代理人买衣服你叫顾客,然而你还是你,同样的,你当老板干的事和你当顾客或者代理人的事情都不一样"你爸爸叫你叫儿子,你爷爷叫你叫孙子")
既然new是代理人,那么肯定有过人之处,在使用new的过程;
1:在函数内部生成一个对象(空对象){ }
2:吧函数内部this引用绑定到这个对象上
3:隐式的返回这个对象(那么也就是说new表达式的值是这个对象)
function GarmentFactory(){
1:在函数内部生成一个对象(空对象){ }//对程序员不可见
var obj={}
2:吧函数内部this引用绑定到这个对象上,这是硬行规定
obj.name="adidas"
obj.color="red"
obj.temperature=function(){}
3:隐式的返回这个对象(那么也就是说new表达式的值是这个对象(那么也就是说new表达式的值是这个对象当然也可以显示返回,不过没必要,自己去了解))
return obj;
}
简写如下形式==》
function GarmentFactory(name,color){
this.name=name
this.color=color
this.temperature=function(){}
}
var obj = newGarmentFactory()
注意:第二步已经将this绑定到返回的这个对象,而对象又通过赋值给了obj,他们的区别在于obj什么都不是,就像你的名字什么也不是,但总得用个什么名字称呼你这个实体吧!!!那么this就指向了obj,他就有属性和方法了,到这里了,我们给obj下一个定义,“他通过这么复杂的方式创建的对象特殊在哪里?即便每次创建对象依然是去调用一遍函数”-----》实际上和字面量是一样的,那为什么要用怎么复杂的方式创建对象?
任何复杂的方法都是为了去解决更复杂的事情,
假设你现在还在生产衣服,那么就会有一个问题(这应该不算是问题),明明每一个衣服都有名字,而且都是相同的,那为什么我们要给每一个衣服取个名字(是不是晕了)。再举个例子,人一生下来是不会走路的,那我为什么不跟着别人学走路而要自己发明一个怎么走路呢?每个人都会走路,但大家走路的姿势又各不相同,总之目的都是一样的,
现在我们先把这个工厂放在一边,我们说说人(就我们自己的特征)
相亲除了问你有什么或者会什么他还能问什么(博主是遭遇过的)
1,人都有什么:每个人都有名字,年龄,眼睛,鼻子...........这些属于一个人的基本特征吧(或者叫属性)(这些都是有状态的,比如年龄会增加,名字会改变,但他们能杀人放火吗?)
2,人都会什么:每个人都会吃饭,睡觉,谈恋爱等等。。。。。这些属于一个人行为吧(这些没有什么状态,但他们是行为,是为了操作状态,语文当中动词描述的哪一类)
总结:我们把这写人的基本特征或者基本行为定义为一个模板,我们是不是就可以造小人了,就比如女娲把他自己当成模板
那我们就开始女娲造人(我们这里要假设人可以在一秒钟学会走路,不然故事没法编了)
function Person(name,color){
this.name=name
this.age=18
this.eat=function(){}
}
var obj1= Person()
var obj2= Person()
var obj3= Person()
在上面的例子当中,obj1,obj2,obj3都是一个个具体的人,他们都可以有名字,年龄,会吃饭等一系列人所具备的(只是我写的少而已),那么我们不禁思考一个问题,每个人的名字的确不一样,年龄也是不一样的,但每个人张嘴吃饭的动作确是一样的,在程序当中,你new出来的实例(就是obj123)他们就相当于我们人生下来不是跟着父母学走路的,而是自己摸索怎么走路的。娶一个名字几秒钟就够了,但是走路就算有人教也得几年吧?
这个时候,就得有一个相对祖先,把她会的继承下来,而不是我们每个人都去发明自己怎么走路
(当然,人本来就是可以继承,但程序中的继承是你生下来马上就会走路蹦迪遛狗了)
prototype就是祖先(官方解释不想说了)
只有函数才有prototype属性,而他的属性值是一个对象(就是一个普通对象)
//下午接着扯,困会瞌睡