博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js继承方式详解
阅读量:6972 次
发布时间:2019-06-27

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

hot3.png

js中继承可以分为两种:对象冒充和原型链方式

    一、对象冒充包括三种:临时属性方式、call()及apply()方式

      1.临时属性方式:      

1 function A(x){2   this.x=x;      this.say = function(){          alert('My name is '+this.name);      }3 }  4  function B(x,y){5   this.tmpObj=A;6   this.tmpObj(x);7   delete this.tmpObj;8   this.id = y;      this.showId = function(){           alert('Good morning,Sir,My work number is '+this.id);      }9 }var simon = new B('Simon',9527);simon.say();simon.showId();

/**/第5、6、7行:创建临时属性tmpObj引用构造函数A,然后在B内部执行,执行完后删除。当在B内部执行了 this.x=x后(这里的this是B的对象),B当然就拥有了x属性,当然B的x属性和A的x属性两者是独立,所以并不能算严格的继承。第5、6、7行有更简单的实现,就是通过call(apply)方法:A.call(this,x);

  2.call()/apply()方式:实质上是改变了this指针的指向

function Person(name){     this.name = name;     this.say = function(){          alert('My name is '+this.name);     }}function F2E(name,id){     Person.call(this,name); //apply()方式改成Person.apply(this,[name]);     this.id = id;     this.showId = function(){          alert('Good morning,Sir,My work number is '+this.id);     }}var simon = new F2E('Simon',9527);simon.say();simon.showId();

  /**/call和apply都可以实现继承,唯一的一点参数不同,func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3])。

 通过对象冒充的方式,无法继承通过prototype方式定义的变量和方法:

function Person(name){     this.name = name;     this.say = function(){          alert('My name is '+this.name);     }}Person.prototype.age = 20;Person.prototype.sayAge = function(){alert('My age is '+this.age)};function F2E(name,id){     Person.apply(this,new Array(name));     this.id = id;     this.showId = function(){          alert('Good morning,Sir,My work number is '+this.id);     }}var simon = new F2E('Simon',9527);simon.sayAge(); //提示TypeError: simon.sayAge is not a function

二、原型链继承(可以继承通过prototype方式定义的变量和方法:

  一:

function Parent(){       this.name = 'mike'; }     function Child(){        this.age = 12;      }  Child.prototype = new Parent();//Child继承Parent,通过原型,形成链条  var test = new Child();  alert(test.age);  alert(test.name);//得到被继承的属性  //继续原型链继承  function Brother(){   //brother构造      this.weight = 60;  }  Brother.prototype = new Child();//继续原型链继承  var brother = new Brother();  alert(brother.name);//继承了Parent和Child,弹出mike  alert(brother.age);//弹出12

  二:

function Person(){     this.name = 'Simon';}Person.prototype.say = function(){     alert('My name is '+this.name);}function F2E(id){     this.id = id;     this.showId = function(){          alert('Good morning,Sir,My work number is '+this.id);     }}F2E.prototype = new Person();var simon = new F2E(9527);simon.say();simon.showId();alert(simon.hasOwnProperty('id')); //检查是否为自身属性

       原型链可以理解成:js中每个对象均有一个隐藏的__proto__属性,一个实例化对象的__proto__属性指向其类的prototype方法,而这个prototype方法又可以被赋值成另一个实例化对象,这个对象的__proto__又需要指向其类,由此形成一条链,也就是前面代码中的 F2E.prototype = new Person();

        缺点显而易见,原型链方式继承,就是实例化子类时不能将参数传给父类,也就是为什么实例二中的function Person()没有参数,而是直接写成了this.name=”Simon”的原因。下面的代码将不能达到预期的效果:

unction Person(name){     this.name = name;}Person.prototype.say = function(){     alert('My name is '+this.name);}function F2E(name,id){     this.id = id;     this.showId = function(){          alert('Good morning,Sir,My work number is '+this.id);     }}F2E.prototype = new Person();  //此处无法进行传值,this.name或者name都不行,直接写F2E.prototype = new Person('wood')是可以的,但是这样的话simon.say()就变成了My name is woodvar simon = new F2E("Simon",9527);simon.say();  //弹出 My name is undefinedsimon.showId();

 

综上分析所得:javascript中最常用的继承模式 组合继承

 //创建基类 function Person(name, age) {   this.name = name;   this.age = age; } //通过原型方式给基类添加函数(这样可以服用此函数) Person.prototype.showName = function () { alert(this.name); } //创建子类 function Student(name, age, score) {   this.score = score;   Person.call(this,name,age); } //把父类的实例赋值给子类的原型 Student.prototype = new Person(); //通过原型方式给子类添加函数(这样可以服用此函数) Student.prototype.showScore = function () {   alert(this.score); } //以下为使用 var student = new Student("zhangsan", 22, 100); student.showName(); student.showScore(); 

 

参照:

            

            

           

转载于:https://my.oschina.net/u/2395167/blog/657875

你可能感兴趣的文章
加载目标文件调试
查看>>
使用Java绘制验证码
查看>>
根据数据库字典项完成地区二级联动
查看>>
前端知识点总结(html+css)部分
查看>>
docker安装elasticsearch
查看>>
设计模式
查看>>
Partitioned Tables and Indexes in SQL Server 2005
查看>>
在Ubuntu下使用命令删除目录
查看>>
初识 Java-监听器
查看>>
ACM 擅长排列的小明
查看>>
FTP相关、用vsftpd搭建ftp、xshell使用xftp传输文件、使用pure-ftpd搭建ftp服务
查看>>
VI/VIM 编辑器
查看>>
PHPGrid 1.4.8 发布,PHP 的 CRUD 框架
查看>>
HNOI 2002 营业额统计(Splay入门)
查看>>
Python面向对象关系
查看>>
OpenCV学习(2)--基本数据结构
查看>>
PCIE错误分析
查看>>
linux服务器开发并发模型
查看>>
YYHS-Floor it(递推+矩阵乘法+快速幂)
查看>>
redis安装
查看>>