JavaScript教程系列之面向对象编程
¶首先来首歌曲来放松一下吧!
有人这样说:这种高大上的东西都是造火箭才用得上的,平时干的都是拧螺丝的活当然用不上咯!
但还是得知道并掌握。。。。!
class继承需要掌握,原型继承知道就好了…
¶一、面向对象编程概述
JavaScript不区分类和实例的概念,而是通过原型(prototype)来实现面向对象编程。
¶1、通过__proto__
来指向Student,并且继承Student的所有属性!
JavaScript它没有“Class”的概念,所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已。
1 |
|
¶2、指向(原型)是可以改变的!
在指向一个类后,可以直接修改他的指向(原型)!
1 |
|
注意:不建议使用`__proto__`来改变指向
¶3、要使用Object.create()
方法
该方法可以传入一个原型对象,并创建一个基于该原型的新对象,但是新对象什么属性都没有
为了方便,可以创建一个函数来接收姓名参数,在函数内部做一下赋值的过程即可!
1 |
|
¶二、关于proto和prototype
prototype
是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象。它是显示修改对象的原型的属性。
__proto__
是一个对象拥有的内置属性(请注意:prototype是函数的内置属性,__proto__
是对象的内置属性),是JS内部使用寻找原型链的属性。
区别参考链接:https://www.cnblogs.com/yangjinjin/archive/2013/02/01/2889103.html
¶三、创建对象
为了区分普通函数和构造函数,按照约定,构造函数首字母应当大写,而普通函数首字母应当小写.
这样,一些语法检查工具如jslint将可以帮你检测到漏写的
new
。本节参考:https://www.liaoxuefeng.com/wiki/1022910821149312/1023022043494624
¶1、原型链
当我们用
obj.xxx
访问一个对象的属性时,JavaScript引擎先在当前对象上查找该属性,如果没有找到,就到其原型对象上找,如果还没有找到,就一直上溯到Object.prototype
对象,最后,如果还没有找到,就只能返回undefined
。
¶数组原型链
Array.prototype
定义了indexOf()
、shift()
等方法,因此你可以在所有的Array
对象上直接调用这些方法。
1 |
|
¶函数原型链
Function.prototype
定义了apply()
等方法,因此,所有函数都可以调用apply()
方法。
1 |
|
¶2、构造函数
用new来调用函数,返回一个对象!
函数内部的this指向新创建的对象!并默认返回this!不需要写return了!
必须写new,不写new,函数返回的是undefined!
1 |
|
此时小明的原型链:
1 |
|
¶3、constructor
用
new Student()
创建的对象还从原型上获得了一个constructor
属性,它指向函数Student
本身:
1 |
|
¶4、公用函数(共享方法)
如果我们通过
new Student()
创建了很多对象,这些对象的hello
函数实际上只需要共享同一个函数就可以了,这样可以节省很多内存。通过够着函数.prototype.函数名来创建公用函数,节省内存!
1 |
|
¶5、解决忘写new的方法
我们还可以编写一个
createStudent()
函数,在内部封装所有的new
操作。
||
:用或符号来实现默认值,毕竟是就近原则的!将new封装后,即可不用写new了,以防忘写!
1 |
|
- 不传参都行
- 也可以这样定义
这样传参传的是一个对象,是不需要顺序的!
1 |
|
¶四、原型继承
本节参考:https://www.liaoxuefeng.com/wiki/1022910821149312/1023021997355072
原型链:
1 |
|
我们必须借助一个中间对象来实现正确的原型链,这个中间对象的原型要指向
Student.prototype
。为了实现这一点,参考道爷(就是发明JSON的那个道格拉斯)的代码,中间对象可以用一个空函数F
来实现:F空函数起到一个桥接的作用!
1 |
|
关于call()函数:https://www.runoob.com/w3cnote/js-call-apply-bind.html
是用来重定义 this 这个对象的!
¶五、class继承
在上面的章节中我们看到了JavaScript的对象模型是基于原型实现的,特点是简单,缺点是理解起来比传统的类-实例模型要困难,最大的缺点是继承的实现需要编写大量代码,并且需要正确实现原型链。
有没有更简单的写法?有!
新的关键字
class
从ES6开始正式被引入到JavaScript中。class
的目的就是让定义类更简单。
用class来写,上面章节中的继承和对象编程就简单多了!
constructor很明显是够着函数!
注意没有
function
关键字!
1 |
|
¶class继承
用
class
定义对象的另一个巨大的好处是继承更方便了。想一想我们从Student
派生一个PrimaryStudent
需要编写的代码量。现在,原型继承的中间对象,原型对象的构造函数等等都不需要考虑了,直接通过extends
来实现:
extends
表示原型链对象来自Student
!使用super()函数来调用父类的(即Student)的构造方法!
class继承和原型继承没有任何区别,
class
的作用就是让JavaScript引擎去实现原来需要我们自己编写的原型链代码。简而言之,用class
的好处就是极大地简化了原型链代码。
1 |
|