这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战
借用构造函数方式继承
构造函数方式实现继承,通过call方式,也可以使用apply方式(自我理解就是调用call,或apply将父类执行了一遍) 通过call实现的继承本质是改变了this的指向,让父类里面的this指到子类的上下文 这样在父类里面通过this设置的属性或方法就会被写到子类上面 缺点:只能继承父类构造函数上的属性和方法,不能继承父类原型上的属性和方法
function Parent(name,age) {
this.p_name = name;
this.p_age = age;
this.p_say = function () {
console.log("parent say")
}
}
Parent.prototype.pp_msg="parent prototype attr"
Parent.prototype.pp_fun = function () {
console.log("parent prototype function")
}
function Child(sex,name,age) {
this.c_sex = sex
Parent.call(this,name,age)
}
var c= new Child("man","tom",12)
console.log(c)
利用原型链方式实现继承
利用原型链的向上查找机制实现继承,给child.prototype = new parent() child2的实例对象的__proto__指向child2构造函数的prototype,child2的prototype指向new出来的这个parent实例对象, 这个parent实例对象的__proto__指向parent的prototype c2本身->c2的__proto__->child2的prototype->parent实例->parent实例的__proto__->parent构造函数的prototype 这样既能继承父类构造函数上的属性,也能继承父类原型上的属性 缺点:1)继承的父类的属性在指定原型对象(child2.prototype = new parent(12,"d"))的时候固定了,默认每个对象继承的父类的属性值都是一样的, 如果要修改,就会有通过实例对象修改原型对象属性的问题(在下面),例如当修改原型对象上的引用类型的属性的属性的时候(不是重新赋值)的时候,创造的所有实例对象的这个属性都变了,相互影响
注意: ! 这里是通过实例对象去修改原型对象上的属性,分3种情况: 1)当原型对象的属性为基础类型时,当通过实例对象修改这样的属性时,不会修改原型对象的属性,会在实例对象上创建一个同名属性 2)当原型对象的属性为引用类型时,当通过实例对象直接赋另外的值给该属性的时候,不会修改原型对象的属性,会在实例对象上创建一个同名属性 3)当原型对象的属性为引用类型时,当通过实例对象修改该引用类型的属性,会直接修改原型上面的属性的值
function Child2(sex) {
this.c_sex = sex
}
Child2.prototype = new Parent("tom",12)
var c2 = new Child2("man")
console.log(c2)