js篇-原型与原型链
prototype属性
每一个构造函数都有一个prototype属性,这个就是原型,每一个对象都会从原型"继承"属性。
__proto__属性
每一个实例都有一个__proto__属性,这个属性指向原型
继承
原型链继承
实现思路:定义两个构造函数,分别为父类(SuperType)、子类(SubType),为了实现子类能够使用父类的属性(本身和原型上面的属性)。重写子类的原型,让子类的原型指向父类实例,这样子类的构造函数就是父类的实例地址,实现子类可以使用父类的本身和原型上的属性
function superType () { } superType.prototype.say = function () { console.log('say hello') } function subType(age) { this.age = age } subType.prototype = new superType(); // 改写子类的原型,为夫类的实例 SubType.prototype.constrcutor = SubType;
优点:子类可以通过原型链的查找,实现父类的属性公用与子类的实例
缺点:
- 一些引用数据操作的时候会出问题,两个实例会公用继承实例的引用数据类
- 谨慎定义方法,以免定义方法也继承对象原型的方法重名
- 无法直接给父级构造函数使用参数
构造函数继承
实现思路:使用call apply方法,通过执行方法修改tihs (上下文),是的父级的this变成子类实例的this,这样每个实例都会得到父类的属性,实现引用属性备份
function superType (name) { this.name = name; } superType.prototype.say = function () { console.log('say hello') } function subType (age, name) { this.age = age; superType.call(this, name) }
优点:解决了父类传递参数问题
缺点:子类的实例只是得到了父类的this绑定的属性,放在父类prototype的属性和方法不可使用
组合继承(原型链+构造函数继承)
实现思路:
- 使用原型链的继承实现,通过原型查找功能来满足原型链共享方法
- 使用借用构造函数方法,使用实例备份父类共享引用类型备份
function superType (name) { this.name = name; } superType.prototype.say = function () { console.log('say hello') } function subType (age, name) { this.age = age; superType.call(this, name) } subType.prototype = new superType(); // 改写子类的原型,为夫类的实例 SubType.prototype.constrcutor = SubType;
缺点:父类的构造函数被实例换了两次 * 实例会有父类的构造函数的一些this属性、子类的构造函数(prototype)上也有一份实例的上有的属性
function superType (name) { this.name = name; } superType.prototype.say = function () { console.log('say hello') } function subType (age, name) { this.age = age; superType.call(this, name) } const props = Object(superType.prototype) props.constrcutor = subType subType.prototype = props // subType.prototype = new superType(); // 改写子类的原型,为夫类的实例