理解javascript对象继承


Posted in Javascript onApril 17, 2016

先从一个问题进行研究深入,什么是javascript对象继承?

比如我们有一个“动物”对象的构造函数。

function animal() {
    this.type = '动物';
  }

还有一个“猫”对象的构造函数。

function cat(name,color) {
    this.name = name;
    this.color = color;
  }

我们知道猫也属于动物,如果这个猫对象想要继承动物对象的属性,我们该怎么做呢?

构造函数绑定
使用构造函数绑定是最简单的方法,使用call或者apply将父对象绑定在自对象上就可以了。

function cat(name,color) {
    animal.apply(this,arguments);
    this.name = name;
    this.color = color;
  }
  var cat1 = new cat("haha", 'red');
  console.log(cat1.type); //动物

不过这种方法比较少见。

拷贝继承
如果把父对象的所有属性和方法,拷贝进子对象,也可以实现继承。

function extend(Child, Parent) {

var p = Parent.prototype;


var c = Child.prototype;


for (var i in p) {



c[i] = p[i];



}


c.uber = p;   //桥梁作用

}

使用方法:

extend(cat, animal);
  var cat1 = new cat("haha","red");
  alert(cat1.type);   // 动物

原型继承(prototype)
相比于上面的直接绑定,原型继承的方法比较常见,对于prototype,我自己简单总结了一下。

每个函数都有一个prototype属性,这个属性是指向一个对象的引用,当使用new关键字创建新实例的时候,这个实例对象会从原型对象上继承属性和方法。

也就是说,如果将“猫”构造函数的prototype属性指向一个“动物”实例,那么再创建“猫”对象实例的时候,就继承了“动物”对象的属性和方法了。

继承实例

cat.prototype = new animal();
  cat.prototype.constructor = cat;
  var cat1 = new cat("haha","red");
  console.log(cat1.constructor == cat);  //true
  console.log(cat1.type); // 动物

1、代码第一行,我们将cat函数的prototype对象指向一个animal对象的实例(其中就包含了animal的type属性了)。

2、代码第二行是什么意思呢?

1)、首先,假如我们没有加这行代码,运行

    cat.prototype = new animal();
    console.log(cat.prototype.constructor == animal);  //true
也就是说,其实每个prototype对象都有一个constructor属性,指向它的构造函数。

2)、我们再看下面的代码

cat.prototype = new animal();
  var cat1 = new cat("haha", 'red');
  console.log(cat1.constructor == animal);  //true

由上我们看到实例cat1的构造函数是animal,所以,显然是不对的。。。cat1明明是new cat()才生成的,所以我们应该手动纠正。cat.prototype对象的constructor值改为cat。

3)、所以这也是我们应该注意的一点,如果我们替换了prototype对象,就应该手动纠正prototype对象的constructor属性。

    o.prototype = {};
    o.prototype.constructor = o;
直接继承prototype
由于在animal对象中,不变的属性可以直接写在animal.prototype中。然后直接让cat.prototype指向animal.prototype也就实现了继承。

现在我们先将animal对象改写成:

function animal() {
  }
  animal.prototype.type = '动物';

然后再实现继承:

cat.prototype = animal.prototype;
  cat.prototype.constructor = cat;
  var cat1 = new cat("haha","red");
  console.log(cat1.type); // 动物

与上一种方法相比,这种方法显得效率更高(没有创建animal实例),节省了空间。但是这样做正确吗?答案是不正确,我们继续看。

    cat.prototype = animal.prototype;
这行代码让cat.prototype和animal.prototype指向了同一个对象,所以如果改变了cat.prototype的某一个属性,都会反映到animal.prototype上,这显然不是我们想要看到的。

比如我们运行:

    console.log(animal.prototype.constructor == animal)  //false
结果看到是false,为什么呢?cat.prototype.constructor = cat;这一行就会把animal.prototype的constructor属性也改掉了。

利用空对象作为中介

var F = function(){};
  F.prototype = animal.prototype;
  cat.prototype = new F();
  cat.prototype.constructor = cat;

结合上面两种方法,因为F是空对象,所以几乎不占内存。这时修改cat的prototype对象,就不会影响到animal的prototype对象。

    console.log(animal.prototype.constructor == animal);   // true
然后我们将上面的方法封装一下:

function extend(Child, Parent) {

var F = function(){};


F.prototype = Parent.prototype;


Child.prototype = new F();


Child.prototype.constructor = Child;


Child.uber = Parent.prototype;

}

使用的时候,方法如下:  

extend(cat,animal);
  var cat1 = new cat("haha","red");
  console.log(cat1.type); // 动物

Child.uber = Parent.prototype; 这行代码就是个桥梁作用,让子对象的uber属性直接指向父对象的prototype属性,等于在自对象上打开一条叫uber的通道,让子对象的实例能够使用父对象的所有属性和方法。

以上就是对javascript对象继承我的理解,希望或多或少能够帮助到大家,谢谢大家的阅读。

Javascript 相关文章推荐
客户端脚本中常常出现的一些问题和调试技巧
Jan 09 Javascript
js 方法实现返回多个数据的代码
Apr 30 Javascript
Javascript生成json的函数代码(可以用php的json_decode解码)
Jun 11 Javascript
php常见的页面跳转方法汇总
Apr 15 Javascript
Javascript显示和隐藏ul列表的方法
Jul 15 Javascript
解决Window10系统下Node安装报错的问题分析
Dec 13 Javascript
详解JavaScript树结构
Jan 09 Javascript
JS实现针对给定时间的倒计时功能示例
Apr 11 Javascript
关于JavaScript 数组你应该知道的事情(推荐)
Apr 10 Javascript
node中实现删除目录的几种方法
Jun 24 Javascript
js实现查询商品案例
Jul 22 Javascript
浅谈JavaScript中this的指向问题
Jul 28 Javascript
node.js连接mongoDB数据库 快速搭建自己的web服务
Apr 17 #Javascript
js如何准确获取当前页面url网址信息
Sep 13 #Javascript
基于javascript实现图片切换效果
Apr 17 #Javascript
非常棒的jQuery图片轮播效果
Apr 17 #Javascript
jQuery实现的倒计时效果实例小结
Apr 16 #Javascript
jQuery实现漂亮实用的商品图片tips提示框效果(无图片箭头+阴影)
Apr 16 #Javascript
jQuery实现无限往下滚动效果代码
Apr 16 #Javascript
You might like
微盾PHP脚本加密专家php解密算法
2020/09/13 PHP
PHP类与对象中的private访问控制的疑问
2012/11/01 PHP
CI框架中site_url()和base_url()的区别
2015/01/07 PHP
Laravel核心解读之异常处理的实践过程
2019/02/24 PHP
Save a File Using a File Save Dialog Box
2007/06/18 Javascript
JS 密码强度验证(兼容IE,火狐,谷歌)
2010/03/15 Javascript
jQuery图片播放8款精美插件分享
2013/02/17 Javascript
jQuery 事件的命名空间简单了解
2013/11/22 Javascript
IE下通过a实现location.href 获取referer的值
2014/09/04 Javascript
jQuery+AJAX实现网页无刷新上传
2015/02/22 Javascript
jQuery中$.each()函数的用法引申实例
2016/05/12 Javascript
javascript时间戳和日期字符串相互转换代码(超简单)
2016/06/22 Javascript
DWR3 访问WEB元素的两种方法实例详解
2017/01/03 Javascript
Angularjs 依赖压缩及自定义过滤器写法
2017/02/04 Javascript
快速将Vue项目升级到webpack3的方法步骤
2017/09/14 Javascript
微信、QQ、微博、Safari中使用js唤起App
2018/01/24 Javascript
jQuery实现百度图片移入移出内容提示框上下左右移动的效果
2018/06/05 jQuery
js HTML DOM EventListener功能与用法实例分析
2020/04/27 Javascript
[00:20]TI9观赛名额抽取Ⅱ
2019/07/24 DOTA
Python3 正在毁灭 Python的原因分析
2014/11/28 Python
Python常用内置函数总结
2015/02/08 Python
Python制作爬虫采集小说
2015/10/25 Python
Python 的类、继承和多态详解
2017/07/16 Python
python 批量解压压缩文件的实例代码
2019/06/27 Python
python 中pyqt5 树节点点击实现多窗口切换问题
2019/07/04 Python
python字符串常用方法及文件简单读写的操作方法
2020/03/04 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
django admin 根据choice字段选择的不同来显示不同的页面方式
2020/05/13 Python
HTML5 Canvas如何实现纹理填充与描边(Fill And Stroke)
2013/07/15 HTML / CSS
美国知名的隐形眼镜电商:Contacts America
2019/11/19 全球购物
可以在一个PHP文件里面include另外一个PHP文件两次吗
2015/05/22 面试题
课外访万家心得体会
2014/09/03 职场文书
2014年连锁店圣诞节活动方案
2014/12/09 职场文书
事业单位岗位说明书
2015/10/08 职场文书
css3中transform属性实现的4种功能
2021/08/07 HTML / CSS
使用CSS实现一个搜索引擎的原理解析
2021/09/25 HTML / CSS