理解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 相关文章推荐
[原创]网络复制内容时常用的正则+editplus
Nov 30 Javascript
工作需要写的一个js拖拽组件
Jul 28 Javascript
网站404页面3秒后跳到首页的实例代码
Aug 16 Javascript
js文件Cookie存取值示例代码
Feb 20 Javascript
JavaScript实现简单图片滚动附源码下载
Jun 17 Javascript
js查找节点的方法小结
Jan 13 Javascript
jQuery仿淘宝网产品品牌隐藏与显示效果
Sep 01 Javascript
jQuery通过ajax请求php遍历json数组到table中的代码(推荐)
Jun 12 Javascript
jQuery选择器中的特殊符号处理方法
Sep 08 jQuery
js自定义trim函数实现删除两端空格功能
Feb 09 Javascript
Vue组件之单向数据流的解决方法
Nov 10 Javascript
vue 解决遍历对象显示的顺序不对问题
Nov 07 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提取数据库内容中的图片地址并循环输出
2010/03/21 PHP
MacOS 安装 PHP的图片裁剪扩展Tclip
2015/03/25 PHP
PHP中实现crontab代码分享
2015/03/26 PHP
php计算年龄精准到年月日
2015/11/17 PHP
解析WordPress中控制用户登陆和判断用户登陆的PHP函数
2016/03/01 PHP
Yii2实现ajax上传图片插件用法
2016/04/28 PHP
PHP设计模式(八)装饰器模式Decorator实例详解【结构型】
2020/05/02 PHP
jquery easyui的tabs使用时的问题
2010/03/23 Javascript
简短几句jquery代码的实现一个图片向上滚动切换
2011/09/02 Javascript
关于IE中getElementsByClassName不能用的问题解决方法
2013/08/26 Javascript
JavaScript中实现最高效的数组乱序方法
2014/10/11 Javascript
js闭包的用途详解
2014/11/09 Javascript
JavaScript模拟鼠标右键菜单效果
2020/12/08 Javascript
JavaScript简单实现弹出拖拽窗口(一)
2016/06/17 Javascript
flexslider.js实现移动端轮播
2017/02/05 Javascript
Angular 4 指令快速入门教程
2017/06/07 Javascript
vue中如何让子组件修改父组件数据
2018/06/14 Javascript
JS的Ajax与后端交互数据的实例
2018/08/08 Javascript
Vue中通过Vue.extend动态创建实例的方法
2019/08/13 Javascript
Vue实现可移动水平时间轴
2020/06/29 Javascript
Python 字典(Dictionary)操作详解
2014/03/11 Python
详解Python中time()方法的使用的教程
2015/05/22 Python
Tensorflow分类器项目自定义数据读入的实现
2019/02/05 Python
对Django中static(静态)文件详解以及{% static %}标签的使用方法
2019/07/28 Python
Python使用Slider组件实现调整曲线参数功能示例
2019/09/06 Python
python3图片文件批量重命名处理
2019/10/31 Python
解决Python 异常TypeError: cannot concatenate 'str' and 'int' objects
2020/04/08 Python
Jupyter notebook如何修改平台字体
2020/05/13 Python
分布式全文检索引擎ElasticSearch原理及使用实例
2020/11/14 Python
Python 删除List元素的三种方法remove、pop、del
2020/11/16 Python
使用JS+CSS3技术:让你的名字动起来
2013/04/27 HTML / CSS
百思买加拿大:Best Buy Canada
2018/03/20 全球购物
斯洛伐克香水和化妆品购物网站:Parfemy-Elnino.sk
2020/01/28 全球购物
新闻专业本科生的自我评价分享
2013/11/20 职场文书
2015年教师党员公开承诺书
2015/01/22 职场文书
使用opencv-python如何打开USB或者笔记本前置摄像头
2022/06/21 Python