博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js实现的几种继承方式
阅读量:4626 次
发布时间:2019-06-09

本文共 4439 字,大约阅读时间需要 14 分钟。

他山之石,可以攻玉,本人一直以谦虚的态度学他人之所长,补自己之所短,望各位老师指正! 拜谢

js几种继承方式,学习中的总结:

所谓的继承是为了继承共有的属性,减少不必要代码的书写

第一种:借用构造函数继承 :可以继承实例属性。但是原型中的方法无法继承

// - 设置需要被继承的构造函数Animal        function Animal(name,age){            this.name = name;            this.age = age;        }        Animal.prototype.eat = function(){            console.log("吃各种吃的");        };        //再设置一个猫咪构造函数        //思考:已经存在的构造函数Animal中具有了一些属性和方法,这些属性与方法时Cat构造函数需要的        //      没有必要再书写一遍了,可以使用继承的方式获取        function Cat(name,age){            //通过call的方式,修改Animal中的this指向为当前Cat的this,并设置参数            Animal.call(this,name,age);        }        var c1 = new Cat("jack",18);        console.log(c1);

第二种:原型继承  

1 好处:可以继承原型中的方法
2 缺点:①实例属性虽然有,但是无法传参(跟没有一样)
      ②要想为子类新增属性和方法,必须要在
new Animal()这样的语句之后执行 否则会被覆盖
      ③无法实现多继承
      ④需要重新设置被覆盖的constructor属性 让constructor重新指向Cat
function Animal(name,age){            this.name = name;            this.age = age;        }        Animal.prototype.eat = function(){            console.log("吃各种吃的");        };                function Cat(color){            this.color = color;        }        //继承的核心代码:        Cat.prototype = new Animal("jack",18);///这点是重要点:必须写在前面 ,否则会覆盖子类的方法        //设置被覆盖的constructor属性 让constructor重新指向Cat        Cat.prototype.constructor = Cat;        Cat.prototype.shangShu = function(){            console.log("猫咪可以爬树");        };      
      var c1=new Cat();
      console.log(c1);
      console.log(c1.name)//jack
      console.log(c1.age)//18
  通过原型链的方法可以查找到属性,但是无法传参
原型链:查找规则,优先查找自身,如果没有则查找__proto__中是否存在; 原型链是用来描述实例对象与原型对象之间关系的一种方式。

第三种:组合继承

 使用前面两种继承方式时发现各有优缺点,所以将两种方式结合即可
 这种结合使用的方式称为组合继承,组合继承是最常用的一种继承方式。    
     function Animal(name,age){
        this.name = name; this.age = age; } Animal.prototype.eat = function(){ console.log("吃各种吃的"); }; function Cat(name,age,color){ //使用借用构造函数的方式继承: Animal.call(this,name,age); this.color = color; } //原型继承的核心代码: //使用组合继承方式后,在构造函数体中就设置了实例属性,此处不需要传参 Cat.prototype = new Animal(); //设置被覆盖的constructor属性 Cat.prototype.constructor = Cat; Cat.prototype.shangShu = function(){ console.log("猫咪可以爬树"); }; var c1 = new Cat("rose",20,"red"); console.log(c1); 在这总结一下原型链: 原型链:查找规则,优先查找自身,如果没有则查找__proto__中是否存在; 原型链是用来描述实例对象与原型对象之间关系的一种方式

①Animal构造函数在设置时没用继承自其它的构造函数

②Animal的原型对象也是一个对象
③对象都是通过Object这个构造函数创建的
④Animal.prototype这个对象__proto__就应该指向Object.prototype
⑤通过观察我们发现确实含有一个属性constructor,并且值为Object构造函数
⑥Object.prototype中没有__proto__属性了,说明这个对象是原型对象的终点。若果使用一个对象的属性时,在整个原型对象中均没找到,值即为undefined Object。prototype.__proto__打印为null
扩展:在作用域中,都没有找到会报错

第四种:对组合继承的优化方式 

个人认为:

虽然可以省去不需要继承的实例属性
这种方式的确会比组合继承的方式性能更好,但是略麻烦(了解即可)
function Animal(name,age){            this.name = name;            this.age = age;        }        Animal.prototype.eat = function(){            console.log("吃各种吃的");        };            function Cat(name,age,color){            //使用借用构造函数的方式继承:            Animal.call(this,name,age);            this.color = color;        }        //原型继承方式中希望获取到Animal的原型方法        //Cat.prototype = new Animal();        //可以省去不需要继承的实例属性        //这种方式的确会比组合继承的方式性能更好,但是略麻烦(了解即可)        function Fun (){}        Fun.prototype = Animal.prototype;        Cat.prototype = new Fun();        Cat.prototype.constructor = Cat;        Cat.prototype.shangShu = function(){            console.log("猫咪可以爬树");        };                var c1 = new Cat("rose",20,"red");        console.log(c1);

第五种:拷贝继承 

使用继承的原型中的方法时,查找的次数会降低
效率较低,内存占用高(因为要拷贝父类的属性)
function Animal(name,age){            this.name = name;            this.age = age;        }        Animal.prototype.eat = function(){            console.log("吃各种吃的");        };             
     function Cat(name,age){
          Animal.call(this,name,age)
        }
     //核心代码
      for(var k in Animal.prototype){
          Cat.prototype[k] = Animal.prototype[k];//添加属性
        }
        Cat.prototype.constructor = Cat;
        Cat.prototype.shangShu = function(){
          console.log("猫咪可以爬树");
        };
        var c1 = new Cat("rose",20,"red");
        console.log(c1);
 

补充一下:对象之间的继承:

var obj={     name:'jack',     age:12,     gender:'男',     sayHai:function(){       console.log(‘我是人)     }   }   问题:obj2想要继承obj的属性   1)拷贝继承:   var obj2={};   for(var k in obj){     obj2[k]=obj[k];   }   2)原型继承:   function Fun(){};   Fun.prototype=obj;   var obj2=new Fun();   console.log(obj2);

 

 

转载于:https://www.cnblogs.com/shengmo/p/8634767.html

你可能感兴趣的文章
URI、URL 和 URN的区别
查看>>
根据表达式序列(前缀、中缀、后缀)构建表达式树
查看>>
mysql性能优化
查看>>
【SqlServer系列】语法定义符号解析
查看>>
Color Length UVA - 1625
查看>>
TLS/SSL
查看>>
zoj2319Beautiful People Dp
查看>>
图片加载 背景色块问题
查看>>
Static Binding (Early Binding) vs Dynamic Binding (Late Binding)
查看>>
搭建git服务器
查看>>
iOS之UIDynamic UI动力学使用步骤
查看>>
poj 2498 动态规划
查看>>
Windows Phone 7中使用PhoneApplicationService类保存应用程序状态
查看>>
MySql数据库的下载和安装卸载
查看>>
JDBC接口核心的API
查看>>
双缓冲技术局部更新原理之派生自View
查看>>
PPAPI插件与浏览器的通信
查看>>
用 query 方法 获得xml 节点的值
查看>>
Hello,Android
查看>>
Sublime Text 3 build 3103 注册码
查看>>