面向对象的几种继承方式
面向对象的几种继承方式
- prototype是原型,是构造函数的一个属性,其值是一个对象,被称为原型对象。
- Constructor 是原型对象的一个属性,其指向这个原型对象的构造函数。
- 构造函数通过new操作符可新建一个实例对象,实例对象拥有一个__proto__属性,指向构造函数的原型对象。
每个对象都有一个私有属性,__proto__属性,其指向其构造函数的prototype(原型对象)属性,这个原型对象也有个自己的__proto__私有属性指向
其构造函数的prototype原型对象,层层向上,直到一个对象的原型为null。根据定义,null没有原型,并且作为原型链中的最后一节。
当需要用到一个对象的属性时,首先会在其属性上找,找不到会在其原型对象上找,在其原型对象上找不到,会在其原型对象的原型对象上找。
- 原型链继承
将父类的实例作为子类的原型对象,给子类的原型对象赋值之后需要将原型对象的构造函数重新指回其构造函数
本质是重写的子类的原型对象,将子类的原型对象指向了父类的实例,所以子类实例的__proto__属性指向其构造函数的prototype原型对象指向父类的实例对象
父类实例对象的__proto__实例属性指向父类实例对象的原型对象,父类原型对象的__proto__属性指向父类的原型对象的构造函数的原型对象Object
对象属性查找规则:
JavaScript 对象是动态的属性“包”(指其自己的属性)。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
当子类原型对象被修改时,会反映到父类的原型对象上
- call继承
在子类构造函数中,执行父类的构造函数,并用call将父类中的this改变成子类的this,但这种方法只能继承父类的私有属性,并且只能继承私有方法
call是Function的方法,对象没有call方法,与call相似的还有apply方法,同样也是改变函数内this的指向,call改变this指向后立即执行函数,参数跟在第一个参数后面,可传多个参数。
apply改变函数内的this指向后不会立即执行函数,并且其第二个参数是一个数组。
- 冒充对象继承(拷贝继承)
遍历父类的实例,拷贝父类实例的所有私有方法给子类的实例赋值。
function Parent(){ // >>>父类
this.x = 100;
}
Parent.prototype.getX = function(){ // >>>给父类的原型对象添加方法
console.log('getX')
}
function Child(){ //>>>子类,在子类中新建一个父类的实例,循环拷贝父类实例上的属性和方法
var p = new Parent();
for(var attr in p){//for in 可以遍历到原型上的公有自定义属性
this[attr] = p[attr]
}
//以下代码是只获得到私有方法和属性,如果不加这个的话就可以遍历到所有方法和属性
/*if(e.hasOwnProperty(attr)){
this[attr] = e[attr]
}
e.propertyIsEnumerable()*///可枚举属性==> 可以拿出来一一列举的属性
}
var p = new Parent();
var c = new Child();
console.dir(c)
-
混合继承
-
组合继承
-
寄生组合继承