转载请标明出处: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. 结合FireBreath在Chrome/FireFox的多进程模式下崩溃一例

    FireBreath是跨浏览器跨操作系统的插件方案,它封装了ActiveX和NPAPI的插件接口,使用统一的API来暴露JSAPI.Chrome和FireFox使用NPAPI,IE使用ActiveX. ...

  2. PS 滤镜——素描算法(二)

    利用另外一种算法完成素描特效的生成. %%% Sketch clc; clear all; Image=imread('4.jpg'); Image=double(Image); [row,col,l ...

  3. jvm内存查看与分析工具

    2.3 JVM的垃圾收集策略   GC的执行时要耗费一定的CPU资源和时间的,因此在JDK1.2以后,JVM引入了分代收集的策略,其中对新生代采用"Mark-Compact"策略, ...

  4. 导入android SlidingMenu 应用

    SlidingMenu is a helpful Android library for developers. It creates a side navigation like the Faceb ...

  5. java--加强之 jdk1.5简单新特性,枚举,注解

    转载请申明出处:http://blog.csdn.net/xmxkf/article/details/9944041 Jdk1.51新特性(静态导入,可变参数,加强for循环,自动拆装箱) 08.ja ...

  6. java--GUI(图形用户接口)

    转载请申明出处:http://blog.csdn.net/xmxkf/article/details/9795435 day22 01-GUI(概述) GUI(图形用户界面) 1. GUI(Griph ...

  7. LeetCode(30)-Pascal's Triangle

    题目: Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, ...

  8. Qt Creator 更改默认构建目录到工程目录下

    Qt Creator 更改默认构建目录到工程目录下 步骤 工具->选项->构建和运行->概要->Default build directory->去掉第一个". ...

  9. 关于Intent

    TCP/IP 协议是Internet国际网络的基础,主要包括TCP,IP,UDP和ICMP等协议 要连上internet,操作系统必须安装TCP/IP协议,TCP/IP协议可以让不同类型,不同操作系统 ...

  10. Map 遍历分析

    1. 阐述 对于Java中Map的遍历方式,很多文章都推荐使用entrySet,认为其比keySet的效率高很多.理由是:entrySet方法一次拿到所有key和value的集合:而keySet拿到的 ...