js的2种继承方式详解


Posted in Javascript onMarch 04, 2014

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

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

function Person(name){
     this.name = name;
     this.say = function(){
          alert('My name is '+this.name);
     }
}
function F2E(name,id){
     this.temp = Person;
     this.temp(name);
     delete this.temp;
     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();

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,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.say();
simon.showId();

缺点:先来看这么一张内存分配图:

在OO概念中,new实例化后,对象就在堆内存中形成了自己的空间,值得注意的是,这个代码段。而成员方法就是存在这个代码段的,并且方法是共用的。问题就在这里,通过对象冒充方式继承时,所有的成员方法都是指向this的,也就是说new之后,每个实例将都会拥有这个成员方法,并不是共用的,这就造成了大量的内存浪费。并且通过对象冒充的方式,无法继承通过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

二、原型链方式
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原型链概念:

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

F2E.prototype = new Person()

这句是关键。js对象在读取某个属性时,会先查找自身属性,没有则再去依次查找原型链上对象的属性。也就是说原型链的方法是可以共用的,这样就解决了对象冒充浪费内存的缺点。

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

function 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();
var simon = new F2E("Simon",9527);
simon.say();
simon.showId();
 
function 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 wood
var simon = new F2E("Simon",9527);
simon.say();  //弹出 My name is undefined
simon.showId();

最后,总结一下自认为较好的继承实现方式,成员变量采用对象冒充方式,成员方法采用原型链方式,代码如下:

function Person(name){
     this.name = name;
}Person.prototype.say = function(){
     alert('My name is '+this.name);
}
function F2E(name,id){
     Person.call(this,name);
     this.id = id;
}
F2E.prototype = new Person(); 
//此处注意一个细节,showId不能写在F2E.prototype = new Person();前面
F2E.prototype.showId = function(){
     alert('Good morning,Sir,My work number is '+this.id);
}
var simon = new F2E("Simon",9527);
simon.say();
simon.showId();
Javascript 相关文章推荐
Google韩国首页图标动画效果
Aug 26 Javascript
2012年开发人员的16款新鲜的jquery插件体验分享
Dec 28 Javascript
5秒后跳转到另一个页面的js代码
Oct 12 Javascript
js浮点数精确计算(加、减、乘、除)
Dec 26 Javascript
基于jQuery+JSON的省市二三级联动效果
Jun 05 Javascript
javascript页面倒计时实例
Jul 25 Javascript
js判断某个字符出现的次数的简单实例
Jun 03 Javascript
Js+Ajax,Get和Post在使用上的区别小结
Jun 08 Javascript
深究AngularJS——ng-checked(回写:带真实案例代码)
Jun 13 Javascript
vue实现页面加载动画效果
Sep 19 Javascript
jQuery length 和 size()区别总结
Apr 26 jQuery
vue首次渲染全过程
Apr 21 Vue.js
Seajs的学习笔记
Mar 04 #Javascript
文本域中换行符的替换示例
Mar 04 #Javascript
为jquery的ajaxfileupload增加附加参数的方法
Mar 04 #Javascript
Document.location.href和.replace的区别示例介绍
Mar 04 #Javascript
LABjs、RequireJS、SeaJS的区别
Mar 04 #Javascript
js的Boolean对象初始值示例
Mar 04 #Javascript
js动态拼接正则表达式的两种方法
Mar 04 #Javascript
You might like
phplock(php进程锁) v1.0 beta1
2009/11/24 PHP
php 读取shell管道传输过来的内容
2010/03/01 PHP
PHP开启opcache提升代码性能
2015/04/26 PHP
Symfony2学习笔记之控制器用法详解
2016/03/17 PHP
PHP使用ajax的post方式下载excel文件简单示例
2019/08/06 PHP
浅谈laravel-admin form中的数据,在提交后,保存前,获取并进行编辑
2019/10/21 PHP
两种常用的javascript数组去重方法思路及代码
2013/03/26 Javascript
jquery判断RadioButtonList和RadioButton中是否有选中项示例
2013/09/29 Javascript
js 距离某一时间点时间是多少实现代码
2013/10/14 Javascript
简单时间提示DEMO从0开始一直进行计时
2013/11/19 Javascript
jQuery学习笔记之jQuery.fn.init()的参数分析
2014/06/09 Javascript
jQuery不兼容input的change事件问题解决过程
2014/12/05 Javascript
javascript关于open.window子页面执行完成后刷新父页面的问题分析
2015/04/27 Javascript
js随机生成字母数字组合的字符串 随机动画数字
2015/09/02 Javascript
JQuery中attr属性和jQuery.data()学习笔记【必看】
2016/05/18 Javascript
JavaScript简单实现弹出拖拽窗口(二)
2016/06/17 Javascript
微信小程序 小程序制作及动画(animation样式)详解
2017/01/06 Javascript
利用JavaScript在网页实现八数码启发式A*算法动画效果
2017/04/16 Javascript
微信小程序如何获知用户运行小程序的场景教程
2017/05/17 Javascript
详解vue-cli 脚手架项目-package.json
2017/07/04 Javascript
详解vue-cli项目中的proxyTable跨域问题小结
2018/02/09 Javascript
JavaScript基础心法 深浅拷贝(浅拷贝和深拷贝)
2018/03/05 Javascript
jQuery 导航自动跟随滚动的实现代码
2018/05/30 jQuery
JavaScript 实现同时选取多个时间段的方法
2019/10/17 Javascript
基于vue.js实现购物车
2020/01/15 Javascript
vue style width a href动态拼接问题的解决
2020/08/07 Javascript
python字符串连接方式汇总
2014/08/21 Python
创建pycharm的自定义python模板方法
2018/05/23 Python
python opencv 批量改变图片的尺寸大小的方法
2019/06/28 Python
基于torch.where和布尔索引的速度比较
2020/01/02 Python
python十进制转二进制的详解
2020/02/07 Python
意大利时尚奢侈品店:D’Aniello Boutique
2021/01/19 全球购物
面临毕业的毕业生自荐书范文
2014/02/05 职场文书
2014年小学元旦活动方案
2014/02/12 职场文书
2016领导干部廉洁自律心得体会
2016/01/13 职场文书
mysql下的max_allowed_packet参数设置详解
2022/02/12 MySQL