前言: 上一章我们用大白话讲解了一下面向对象的编程思维,那么这一张我们来讲讲如何用面向对象来书写代码。终于到了激动人心的时刻了..... 传送门:https://www.cnblogs.com/sy11112027/p/10740906.html 上一篇的地址
面向对象的三大特征: 在了解了面向对象的编程思维后我们继续了解下面向对象的三大特征从而深刻的理解一下面向对象 抽象:抓住核心问题 如何想描述一个人的时候我们应该如何去描述?用不用把这个人的每一个身体的器官,以及每一段经历都书写出来?那么我敢说你要是想了解我的话,你至少的写2本书才能把我 描述出来,但是在我们面向对象的三大特征中的抽象就不需要这么麻烦,你只需要知道我这个人的姓名,年龄,外贸,以及一些主要的信息就可以了。也就是说你只需要把问题 的核心部分拿到手里面就可以了,这就是所谓的抽象 封装:不考虑内部实现,只考虑功能使用 当我们驾驶汽车的时候,是否要知道发动机的原理? 当我们打开电视机的时候,是否要知道它的电路结构? 当我们玩电脑的时候,是否要精通计算机的硬件组成? 当我们打游戏的时候,是否必须明白程序的实现原理? 其实以上一些问题我们都不需要去了解内部的一些构造,其实封装也是如此:把一些功能封装好,留一个用口 继承:从已有的对象上继承出新的对象 说到继承,不得不说下我自己,我一直以为我的家族是一个拥有亿万资产的庞大家族,而我现在所经历的一切都是父亲给我安排好的磨练,如今快过了小三十年了。我才发现我 想多了,其实继承最好理解就是你可以继承你父亲的遗产,或者你父亲的一些面貌特征,编程也是如此 多态:哈哈哈,你们很庆幸,因为javascript中没有多态 好了了解完面向对象的三大特征,那么下面我们真的真的来看看面向对象是如何编写代码的
构造函数: 首先我们先来聊一聊构造函数,等下?不是说要讲如果用面向对象的思维来编写代码吗?怎么现在又扯到了构造函数? 不要着急小伙子,我们一步一步来,因为面向对象的编程风格都是从一个关键字 new 开始的 什么是构造函数? 通过new 调用的函数 叫做构造函数 在讲构造函数的时候我们先来想一个问题,如何创建一个对象?听到这个问题有些同学就安奈不住自己拿躁动的小心灵了,这还不简单? var obj = new Object(); var obj = Object(); var obj = {}; 好既然这么厉害,那我的要求再次升级,能不能用你知道的对象给我描述一个人?这是时候你又安奈不住你幼小的心灵了!!! var obj = { name:"凡尘", age:"18", sex:"帅哥", show:function(){ console.log("凡尘是个大帅哥") } } 是不是感觉分分钟就写完了?那么好,我的需求在此升级,你给我描述10个人的信息!!!这时候你是不是就开始复制粘贴了?然后粘贴了满屏的代码?这又是何苦呢? 难到我们就不能封装一个吗? function person(name,age,sex){ var obj = new Object(); obj.name = name; obj.age = age; obj.sex = sex; obj.showName = function(){ console.log("我的名字叫"+this.name) } obj.showAge = function(){ console.log("我的年龄"+this.age) } return obj; } ----------------------------------------------------------------------------------------------------------------------------------------------- 这时候你是不是感觉你又行了?感觉你特别厉害了?其实这种方式其实就是一个工厂函数,我们可以逐步的接下一下
function person(name,age,sex){ //原料 var obj = new Object(); //加工 obj.name = name; obj.age = age; obj.sex = sex; obj.showName = function(){ console.log("我的名字叫"+this.name) } obj.showAge = function(){ console.log("我的年龄"+this.age) } //出厂 return obj; }
这时候是不是问题就完美的解决掉了呢?不不不,问题才刚刚开始,因为我刚才说过了面向对象的编程风格都是从一个关键字 new 开始的 很明显我们在调用这个函数的时候根本没有用到new这个关键字。 那么问题又来了,为什么非要扯上这个new 难到没有这个new就不行吗?不要急躁我们一步一步来 首先我们把问题列出来看看问题在哪? 1、在调用这个函数的时候我们没有用 new 而new这个关键字在函数的内部使用了。那么我们能不能把这个new给拿出来? 2、上面的栗子中有一个showName方法。那么每次调用这个方法的时候showName方法是否为同一个方法? 如:var b1 = person(name,age,sex); var b2 = person(name,age,sex); alert(b1.showName == b2.showName)//false 既然问题列出来了,那么我们就去解决这2个问题
1、在调用这个函数的时候我们没有用 new 而new这个关键字在函数的内部使用了。那么我们能不能把这个new给拿出来? 问题一: 为什么我非要在调用函数的时候要加一个new呢?好我来解决下这个问题
通过这张图我们很明显就可以看出了区别:
普通函数调用的时候this的指向是window 而构造函数调用的时候this的指向是这个对象
普通函数没有return的时候返回值是undefined 而构造函数的返回值想自己本身这个对象 为什么构造函数没有return却能够有返回值呢? 因为构造函数在调用的时候系统内部自动return出了一个this,而这个this就是指的这个对象 现在我们知道了调用函数的时候加new 和不加new的区别了那我们就来改上面的代码!
打印结果是:凡尘 18
好累啊!!!!终于解决完第一个问题了,那么我们继续来解决第二个问题
2、上面的栗子中有一个showName方法。那么每次调用这个方法的时候showName方法是否为同一个方法? 我们先来验证一下是否为同一个方法
为什么会是一个false呢???如果你听过凡尘老师讲课的话,在ES6的一张说过一道面试题。
创建构造函数的时候js执行了那些操作?
1、在内存中开辟了一块空间
2、把this的指向指向了它
因为new一次就会开辟一块空间,你还指望他们相等吗?就相当于你盖了一个房子,然后买了一个100英寸的电视,然后你发小也盖了一个房子,然后也买了一个100英寸的电视,你难到能说他加的
电视就是你家的电视吗?
既然知道了问题的所在那么我们就去解决这个问题。接下来我们在去扯扯数组
我们都知道数组有好多方法共我们使用,例如 push pop shift.....那么数组有没有一种去重的方法共我们使用呢?例如就叫norepeat?
不用试也应该知道根本没有这个方法。那么我们可不可以给数组加上这个方法呢?当然可以,首先我们要先知道push pop shift....等这些东西在数组的哪里放着。接下来我们学习一个
新的东西叫原型----prototype
我们在页面上输出这样一句话,Array代表数组,也就是说来看下数组的原型。我看可以看下打印出来了什么东西;
你会发现你找到了一个窝点,里面有好多我们熟悉的方法。那么我就可以肯定数组的那么方法是加在原型上面的。那么我们接下来就给数组添加一个norepeat方法
那么别的数组可以使用这个方法吗?他们这个方法是一样的吗?接下来我们去验证这个问题!!!!
经过验证准确无误!!!大功告成,这样我们终于把这两个问题解决完了,那么我们在从新写下我们最开始的那个工厂函数
终于完成了!!!!码字码的好辛苦!!!等这不是说带我们用面向对象的思维写代码吗?怎么就结束了呢? 其实上面的过程和步骤就是利用面向对象的思维去写的,我们稍微总结一波你们就懂了 1、以前我们的全局变量都是为一个人进行服务的,但是现在我们把变量变成了属性,面向对象就可以对所有的人进行服务,而且全局变量会让你的程序变的特别慢,其实你也可以理解成 婚前谁也不属于谁,但是婚后你就只属于对方了 2、我们把所有的函数都加在了对象的原型上面,其实就相当于就每一个方法分割成了不同的模块。这个正好就是我们面向对象的编程思维 截止到目前为止除了面向对象的继承没有讲到以外,其他的应该都已经说到了。如何你能接受这个两篇文章那么你就能用面向对象的思维去编写程序了!!! 具体如何用 面向对象写程序呢?我大致分为以下几个步骤
1、把面向过程的程序,改写成面向对象的形式
2、改写成面向对象的几个条件
a、所有的东西写在onload里面
b、不能有函数嵌套,可以有全局变量
3、 全局变量---》属性 函数---方法 onload ====构造函数
4、改错
后面我会带大家写几个面向对象的案例,今天就到此结束吧,太累了!!!!亲记得给个5星好评
【注】:如需转载请注明出处,码字不容易!请理解----如有不同理解,请大神多多指点
【注】:转载至Alley-巷子的作品,强烈推荐,一名大牛级别的导师!
传送门:http://www.cnblogs.com/nanianqiming/p/7711496.html