关于JS中面向对象的理解 oop(Object Oriented Programming)
它是一种编程思想,我们的编程或者学习其实是按照类
、实例
来完成的
学习类的继承/封装/多态
封装
把实现一个功能的代码封装到一个函数(类),以后再想实现这个功能,只需要执行函数方法即可,不需要再重复的编写代码
低耦合,高内聚:减少页面中冗余代码,提高代码的重复使用率
多态
一个类(函数)的多种形态
重载
后台编程语言中,对于重载的改变:方法名相同参数不同,叫做方法的重载
JS中的重载,同一个方法,通过传递不同的实参我们完成不同的功能,我们把这个也可以理解为重载
重写
不管是后台语言还是JS都有重写,子类重写父类的方法
类的继承
什么是继承?
让子类的原型指向父类的实例
1 Children.prototype = new Parent();
[细节]
我们首先让子类的原型指向父类的实例,然后再向子类原型上扩展方法。,目的是为了防止提前增加方法,等原型重新趾向后,之前再子类圆形上扩展的方法都没用了(子类原型已经指向新的空间地址)
让子类原型才重新指向父类实例,子类原型上原有的constructor
就没了,为了保证构造函数的完整性,我们最好给子类的原型冲洗手动设置constructor
Children.prototype.constructor = Children
[原理]
原型继承,并不是把父类的属性和方法copy一份给子类,而是让子类的原型和父类原型之间搭建一个链接的桥梁,以后子类(或者子类的实例),可以通过原型链的查找机制,找到父类原型上的方法,从而调取这些方法使用即可
Children.prototype.__proto__.setX = function...
子类通过原型链找到父类的原型,再父类原型上增加新的属性和方法(重写:子类重写父类原型上的方法)
[特征]
子类不仅可以继承父类原型上的共有属性和方法,而且父类提供给实例的那些私有属性和方法,也被子类继承了(存放在子类的原型上,作为子类共有的属性和方法)
call继承
1 2 3 4 5 6 7 8 9 10 11 function Parent ( ) { this .x = 100 ; } Parent.prototype.getX = function ( ) { console .log(this .x); } function Children ( ) { Parent.call(this ); this .y = 200 ; } var child = new Children();
[原理]
原理是把父类构造体当中私有的属性和方法,复制一份给子类的实例(继承完成后子类和父类是没关系的)
[细节]
我们一般把call继承放在子类构造体的第一行,也就是创建子类实例的时候,进来的第一件事情就是先继承,然后再给实例赋值自己私有的(好处:可以把继承过来的记过替换掉)
寄生组合继承
Object.create([obj]):创建一个空对象,把[obj]作为心创建对象的原型
子类公有的继承父类公有的(原型继承)
子类私有的继承父类私有的(call继承)
1 2 3 4 5 var Obj = {name : 'aa' }var newObj = Obejct.create(obj);newObj.__proto__ = obj;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function Parent ( ) { this .x = 100 ; } Parent.prototype.getX = function ( ) { console .log(this .x); } var obj = Obejct.create(Parent.prototype);function Children ( ) { Parent.call(this ); this .y = 200 ; } Children.prototype = Object .create(Parent.prototype); Children.prototype.constructor = Children; Children.prototype.getY = function ( ) { console .log(this .y); }
1 2 3 4 5 6 7 Object .myCreate = function myCreate (obj ) { var Fn = new Function (); Fn.prototype = obj; return new Fn(); }; var aa = {name : 'aa' };Object .myCreate(aa);
ES6中的类
创建类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Fn { constructor (){ this .xxx = xxx; } getX(){ } setX(){ } static xxx(){ } }; var f = new Fn();
继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class A { constructor (){ this .x = 100 ; } getX(){ console .log(this .x); } } class B extends A { constructor (){ super (); this .y = 200 ; } getY(){ console .log(this .y); } } var b = new B();
for in 循环问题
不仅可以遍历当前对象(或者实例)所有的私有属性和方法,还可以把原型上自己创建的公共属性和方法进行遍历
for循环只会遍历私有地属性和方法,自己在原型上扩展的方法不会被遍历出来
1 2 3 4 5 6 7 Object .prototype.myXX = function ( ) { }; var obj = {name : 'aa' };for (var i in obj){ console .log(i); }