继承

121 阅读2分钟

构造函数借助call

  • call能在特定的作用域中调用函数,能改变函数的作用域,实际上是改变函数体内 this 的值 。
function parent(){
    this.name = 'a';
}
function child(this){
    parent.call(this) //parent 使用了.call 拿到了parent 的属性
 }
 let c = new child;
 console.log(c);

image.png

  • 但子类只能拿到父类的属性值,一旦父类原型对象存在某一个方法,子类就不能够继承,所以我们做一下改进

借助原型链继承

 function parent() {
     this.name = 'a';
     this.num = [1,2,3,4]; 
 }
 function child() { 
     
 }
 child.prototype = new parent();
 let c = new child();
 console.log(c.name);
 console.log(c.num);

image.png

  • 父类的属性和方法都能够访问,但这里很容易忽略一个bug,
 function parent() {
     this.name = 'a';
     this.num = [1,2,3,4];
 }
 function child() { 
     
 }
 child.prototype = new parent();
 let c = new child();
//  console.log(c.name);
//  console.log(c.num);
 let d = new child();
 d.num.push(5);
 console.log(c.num,d.num)

image.png

  • 我们明明是把对象d的play属性加了个5,c的属性也跟着变了。原来我们c , d都是 同一个原型对象 所以我们再做改进

组合一下

function parent() {
     this.name = 'a';
     this.num = [1,2,3,4];
 }
 function child() { 
     parent.call(this)   // 加了这一行代码
     
 }
 child.prototype = new parent();
 let c = new child();
//  console.log(c.name);
//  console.log(c.num);
 let d = new child();
 d.num.push(5);
 console.log(c.num,d.num)

image.png

  • 这样就解决是同一个原型对象的问题了,但问题又多了一个,我们在child.prototype = new parent()这一步又要去调用parent(),我们再进一步优化。

优化1

  • 我们倒不妨直接把父类的原型对象直接复制给子类
 function parent() {
     this.name = 'a';
     this.num = [1,2,3,4];
 }
 function child() { 
     parent.call(this)
     
 }
 child.prototype = parent.prototype;  //把 new parent() 改成  parent.prototype
 let c = new child();
//  console.log(c.name);
//  console.log(c.num);
 let d = new child();
 d.num.push(5);
 console.log(c.num,d.num)

image.png

  • 果然我们这样可以实现,不过我们好像是把父类的属性方法都继承过来了,但子类实例的构造函数是Parent4,显然这是不对的,应该是Child4。?

image.png

优化2-寄生组合继承


 function parent() {
     this.name = 'a';
     this.num = [1,2,3,4];
 }
 function child() { 
     parent.call(this)
     
 }
 child.prototype = Object.create(parent.prototype);
 child.prototype =parent.prototype
 child.prototype.constructor = child;
 let c = new child();
//  console.log(c.name);
//  console.log(c.num);
 let d = new child();
 d.num.push(5);
 console.log(c)

image.png

总结

学习别人的文章,再拿到自己手里再去实现,自己写篇文章也能很好捋清思路,学得更透彻,也不失为一种很好的学习方法

参考文章 :juejin.cn/post/684490…