javaScript 原型链

回顾知识:构造函数会有一个原型对象属性(prototype),原型对象有一个指针指回构造函数,而实例都包含一个指向原型对象的内部指针(__ proto__)。
原型链概念:让原型对象等于另一个类型的实例,另一个类型的实例的原型又是指向原型对象,这样层层递进,实现了继承。

function Father(){
    this.name = "hzs";
    this.age = 22;
}
Father.prototype.getPersonValue = function(){
    return this.name
}
function Children(){
    this.name = "yqe"
}
// 继承了父类
Children.prototype = new Father();
// 在子类增加新的属性,要放在替换原型之后去做
Children.prototype.getChildrenValue = function(){
    return this.age;
}
Children.prototype.text = "课本";
let chil = new Children();
console.log(chil.getChildrenValue()); // 22
复制代码

原型链问题:(1)引用类型值的原型共享给所有继承,值会受到它们的影响;(2)创建子类型的实例时,不能向超类型函数传递参数

function Father() {
    this.colors = ['red', 'green', 'purple'];
}
function Children() {
    this.name = "yqe"
}
// 继承了父类
Children.prototype = new Father();
let chil = new Children();
let chilT = new Children();
chil.colors.push("black");
console.log(chil.colors); //["red", "green", "purple", "black"]
console.log(chilT.colors); //["red", "green", "purple", "black"]
复制代码

解决方法:借用构造函数

function Father(name) {
    this.colors = ['red', 'green', 'purple'];
    this.name = name;
}
// 用call方法在子类型构造函数中调用超类型的构造函数。
function Children() {
    this.name = "yqe"
    Father.call(this, 'huangzishuan');
}
console.log(chil.colors); //["red", "green", "purple", "black"]
console.log(chilT.colors); //["red", "green", "purple"]
复制代码

结果:通过使用call方法,实际是在将要创建children实例的环境下调用Father构造函数,这样一来,就会在新Children对象上执行Father函数中定义的所有对象初始化代码。结果,每个Children的实例就有自己的colors属性的副本了。
缺陷:父类原型,子类访问不了

解决方法:组合继承

function Father() {
    this.colors = ['red', 'green', 'purple'];
}
Father.prototype.sex = "男";
Father.prototype.remove = function() {
  console.log(
}
function Children() {
    this.name = "yqe"
    Father.call(this);
}
// 继承了父类
Children.prototype = new Father();
Children.prototype.constructor = Children;
let chil = new Children();
let chilT = new Children();
chil.colors.push("black");
console.log(chil.colors);//["red", "green", "purple", "black"]
console.log(chilT.colors);//["red", "green", "purple"]
chil.remove();//"father原型的方法"
复制代码

结果:组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点。实现父类引用类型不会被实例干扰,和子类可以传参给父类。
缺陷:需要调用两次父类构造函数

解决方法:寄生组合继承

function inheritPrototype(children, father) {
  let prototype = Object(father.prototype); 
  prototype.constructor = children;
  children.prototype = prototype;
}
function Father() {
    this.colors = ['red', 'green', 'purple'];
}
Father.prototype.sex = "男";
Father.prototype.remove = function() {
  console.log(father原型的方法);
}
function Children() {
    this.name = "yqe"
    Father.call(this);
}
inheritPrototype(Children, Father);
// 继承了父类
let chil = new Children();
let chilT = new Children();
chil.colors.push("black");
console.log(chil.colors);//["red", "green", "purple", "black"]
console.log(chilT.colors);//["red", "green", "purple"]
chil.remove();//"father原型的方法"
复制代码

结果:这个例子体现在只调用了一次Father构造函数,同时原型链还能保持不变。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享