js 面向对象编程 OOP
用对象的思想去写代码,就是面向对象编程。
es5
1 | // 定义一只喵 |
es6
1 | // 定义一只喵 |
继承
所谓继承就是通过某种方式让一个对象可以访问到另一个对象中的属性和方法。
原型属性和方法:所有人共同使用一个
实例属性和方法:每个人都有一份
静态属性和方法:不能在类的实例上调用静态方法,而应该通过类本身调用。
原型链继承:
继承的本质就是复制,即重写原型对象,代之以一个新类型的实例。
原型链方案存在的缺点:多个实例对引用类型的操作会被篡改。
缺点: 继承了两个对象的属性,this的属性 + 原型的属性。
1 | function parent(){ |
借用构造函数继承
使用父类的构造函数来增强子类实例,等同于复制父类的实例给子类(不使用原型)
优点:
获得父类自身成员的副本,不存在子对象修改父类对象的属性风险。
缺点:
只能继承父类的实例属性和方法,不能继承原型属性/方法
无法实现复用,每个子类都有父类实例函数的副本(深拷贝),影响性能
1 | function parent(){ |
组合模式继承 -> 借用构造函数+原型继承
- 定义:
前两种结合。即:先借用构造函数,还设置子构造函数的原型为父构造函数的实列对象。 - 优点
1.获得父类自身成员的副本 + 父对象中可复用的功能(原型成员方式实现的)
2.子类可向父类构造函数传参
3.可安全修改自身属性 不会修改父类
- 缺点:
实例对象instance1上的两个属性就屏蔽了其原型对象SubType.prototype的两个同名属性。所以,组合模式的缺点就是在使用子类创建实例对象时,其原型中会存在两份相同的属性/方法。
1 | function SuperType(name){ |
原型式继承
缺点:
原型链继承多个实例的引用类型属性指向相同,存在篡改的可能。
无法传递参数
另外,ES5中存在Object.create()的方法,能够代替上面的object方法。
1 | function object(obj){ |
共享原型
定义:
子对象的原型设置成父对象的原型即可。
缺点: 子类或者孙类修改原型,父类会被篡改。
1 | function inherit(C,P){ |
临是构造函数
解决共享原型带来的篡改问题,且可以继续受益原型链的好处
1 | function inherit(C,P){ |
寄生式继承
核心:在原型式继承的基础上,增强对象,返回构造函数
1 | function createAnother(original){ |
寄生组合式继承
结合借用构造函数传递参数和寄生模式实现继承
1 | function inheritPrototype(subType, superType){ |
ES6中class的继承(新)
1 | class Point { /* ... */ } |
Object.getPrototypeOf()
方法可以用来从子类上获取父类。可以判断一个类是否继承了另一个类。
1 | class Point { /*...*/ } |
继承转载自JavaScript常用八种继承方案 by 程序员依扬
转载自阮一峰老师