转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/29194261

1、基于类的继承

下面看下面的代码:

 <script type="text/javascript">

        function Person(name, age)
{
this.name = name;
this.age = age;
}
Person.prototype.say = function ()
{
console.log(this.name + " , " + this.age);
}
function Student(no)
{
this.no = no;
}
<span style="white-space:pre"> /**
         * Student的prototype指向Person的对象
         */</span>
Student.prototype = new Person();
var stu1 = new Student("0001");
stu1.name = '张三';
stu1.age = '11';
console.log(stu1.no);
stu1.say(); </script>

输出结果:

0001
张三 , 11

可以看到Student成功集成了Person,并且拥有了Person的say方法,核心代码其实就是一句 Student.prototype = new Person();,下面通过图解来说明原理:

将Student.prototype指向new Person() , new Person的_proto_又指向Person Prototype;这样完成了整个继承。

但是这种方式存在问题:

问题1:当父类存在引用类型变量时,造成数据不一致,下面我们给Person添加一个hobbies属性,类型为数组。

 <script type="text/javascript">
/**
* 存在问题
* 1、无法在Student的构造方法中传递参数用于父类的构造方法
* 2、对于引用类型变量,造成数据不一致
*/ function Person(name, age)
{
this.name = name;
this.age = age;
this.hobbies = [] ;
}
Person.prototype.say = function ()
{
console.log(this.name + " , " + this.age +" , " +this.hobbies);
}
function Student(no)
{
this.no = no;
}
Student.prototype = new Person(); var stu1 = new Student("0001");
stu1.name = '张三';
stu1.age = '11';
stu1.hobbies.push("soccer");
stu1.say(); var stu2 = new Student("0002");
stu2.name = '李四';
stu2.age = '12';
stu2.hobbies.push("girl");
stu2.say(); </script>

输出结果:

张三 , 11 , soccer
李四 , 12 , soccer,girl

可以看出,李四的hobbies应该只有girl,但是上面的代码让所有对象共享了hobbies属性。

上述的继承方式还存在一个问题:

问题2:在Student的构造方法中,无法使用new Student("00001" , "张三" , 12) ;创建对象,并初始化name和age属性,必须stu.name, stu.age进行赋值

为了解决上述问题,对上述代码进行修改:

 <script type="text/javascript">

        function Person(name, age)
{
this.name = name;
this.age = age;
this.hobbies = [];
}
Person.prototype.say = function ()
{
console.log(this.name + " , " + this.age +" , " + this.hobbies);
} function Student(name, age, no)
{
/**
* 使用call方法,第一个参数为上下文;
* 有点类似Java中的super(name,age)的感觉
*/
Person.call(this, name, age);
this.no = no;
} Student.prototype = new Person(); var stu1 = new Student("0001","张三",11);
stu1.hobbies.push("soccer");
stu1.say(); var stu2 = new Student("0002","李四",12);
stu2.hobbies.push("cangjin");
stu2.hobbies.push("basketball");
stu2.say(); </script>

输出:

0001 , 张三 , soccer
0002 , 李四 , cangjin,basketball

在Student的构造方法中使用了Person.call(this,name,age)感觉就像super(name,age)【call的第一个参数为上下文】;并且成功解决了对引用属性的共享问题,完美解决。

2、基于原型链的继承
    <script type="text/javascript">

        /**
* 基于原型链的集成中都是对象
* 存在问题:
* 1、对于引用类型变量,造成数据不一致
*/
var Person = {
name: "人",
age: 0,
hobbies: [],
say: function ()
{
console.log(this.name + " , " + this.age + " , " + this.hobbies);
}
}
; var Student = clone(Person);
Student.no ="";
Student.sayHello = function()
{
console.log(this.name +"hello ") ;
} var stu1 = clone(Student);
stu1.name = "zhangsan";
stu1.age = 12;
stu1.hobbies.push("Java");
stu1.say(); var stu2 = clone(Student);
stu2.name = "lisi";
stu2.age = 13;
stu2.hobbies.push("Javascript");
stu2.say(); /**
* 返回一个prototype执行obj的一个对象
* @param obj
* @returns {F}
*/
function clone(obj)
{
var F = function ()
{
};
F.prototype = obj;
return new F(); } </script>

输出:

zhangsan , 12 , Java
lisi , 13 , Java,Javascript

可以看出同样存在引用属性不一致的问题,并且整个操作全部基于对象,给人的感觉不是很好,下面通过图解解释下原理:

对象间通过一个clone函数,不断的返回一个新的对象,且prototype执行传入的对象,整个继承过程其实就是_proto_不断的指向,形成一个链,所以叫做原型链。

好了,已经介绍完了,js的两种集成的方式,最好使用的还是通过类的继承(上述第一种方案,解决存在问题的)。

如果代码或者讲解存在任何问题,欢迎留言指出。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Javascript 进阶 继承的更多相关文章

  1. Javascript 进阶 面向对象编程 继承的一个样例

    Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承.这篇使用一个样例来展示js怎样面向对象编程.以及怎样基于类实现继承. 1. ...

  2. Javascript 进阶 面向对象编程 继承的一个例子

    Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承,这篇使用一个例子来展示js如何面向对象编程,以及如何基于类实现继承. 1. ...

  3. JavaScript进阶之路(一)初学者的开始

    一:写在前面的问题和话 一个javascript初学者的进阶之路! 背景:3年后端(ASP.NET)工作经验,javascript水平一般般,前端水平一般般.学习资料:犀牛书. 如有误导,或者错误的地 ...

  4. JavaScript进阶(十一)JsJava2.0版本

    JavaScript进阶(十一)JsJava2.0版本 2007年9月11日,JsJava团队发布了JsJava2.0版本,该版本不仅增加了许多新的类库,而且参照J2SE1.4,大量使用了类的继承和实 ...

  5. javascript进阶课程--第二章--对象

    javascript进阶课程--第二章--对象 学习要点 理解面向对象的概念 掌握对象的创建方法 掌握继承的概念和实现方法 基本概念 对象究竟是什么?什么叫面向对象编程? 对象是从我们现实生活中抽象出 ...

  6. javascript进阶教程第二章对象案例实战

    javascript进阶教程第二章对象案例实战 一.学习任务 通过几个案例练习回顾学过的知识 通过案例练习补充几个之前没有见到或者虽然讲过单是讲的不仔细的知识点. 二.具体实例 温馨提示 面向对象的知 ...

  7. JavaScript进阶知识点——函数和对象详解

    JavaScript进阶知识点--函数和对象详解 我们在上期内容中学习了JavaScript的基本知识点,今天让我们更加深入地了解JavaScript JavaScript函数 JavaScript函 ...

  8. Javascript模拟继承(赠送.net吐槽一段)

    首先吐槽一句,今年的就业形势很不乐观啊,特别是搞.net的(相对java),特特别是还没出校门没有正式工作经验的,找个实习很难,前些天接了个面试电话,上来就质疑我“你一个在校大学生怎么可能做了那么多项 ...

  9. 详解Javascript的继承实现(二)

    上文<详解Javascript的继承实现>介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构 ...

随机推荐

  1. shell脚本调用python脚本的路径问题

    脚本的相互调用中,只有在同一级目录下才可以使用__file__参数去获取路径名,(在shell里使用pwd也同样),否则,使用的就是主文件(最开始运行的脚本程序)的所在位置,是错误路径:一定要注意当期 ...

  2. MfgTool (i.MX53)使用

    1 Introduction The MfgTool is a manufacturing tool from Freescale that runs under Windows. It is des ...

  3. hadoop小知识札记

    hadoop实现全局变量: 只读的可以,可修改的不行,只读的可以通过configuration 或者分布式缓存实现.   hadoop做图像处理时,每个map读入一个图片,每个map读入一张图片,然后 ...

  4. ubuntu12.04:jdk7:手动安装

    总的原则:将jdk-7u10-linux-x64.tar.gz压缩包解压至/usr/lib/jdk,设置jdk环境变量并将其修改为系统默认的jdk 将jdk-7u5-linux-x64.tar.gz拷 ...

  5. CALayer简介

    一.什么是CALayer * 在iOS系统中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮.一个文本标签.一个文本输入框.一个图标等等,这些都是UIView. * 其实UIView之所以 ...

  6. 高并发教程-基础篇-之nginx负载均衡的搭建

    温馨提示:请不要盲目的进行横向扩展,优先考虑对单台服务器的性能优化,只有单台服务器的性能达到最优化之后,集群才会被最大的发挥作用. 一.架构图: 服务器准备:3台,ubuntu16.04系统maste ...

  7. SpringBoot整合ElasticSearch实现多版本的兼容

    前言 在上一篇学习SpringBoot中,整合了Mybatis.Druid和PageHelper并实现了多数据源的操作.本篇主要是介绍和使用目前最火的搜索引擎ElastiSearch,并和Spring ...

  8. docker的安装和技巧

    工作了有一段时间,开发环境中需要docker环境,但是docker一直不算很熟,之前一直是利用yum安装,但是yum安装真的很费劲,所以总结了一些经验给大家: 1,利用yum直接安装 官网是直接给了y ...

  9. Angular TypeScript开发环境集成jQuery扩展插件

    集成步骤: 1.安装jquery极其扩展插件库ts定义文件 npm install jquery --save npm install --save-dev @types/jquery npm ins ...

  10. ajax接收php返回得到一堆html代码

    ajax接收php返回得到一堆html代码 一.      错误代码: <font size='1'><table class='xdebug-error xe-notice' di ...