Javascript 进阶 继承
转载请标明出处: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 进阶 继承的更多相关文章
- Javascript 进阶 面向对象编程 继承的一个样例
Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承.这篇使用一个样例来展示js怎样面向对象编程.以及怎样基于类实现继承. 1. ...
- Javascript 进阶 面向对象编程 继承的一个例子
Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承,这篇使用一个例子来展示js如何面向对象编程,以及如何基于类实现继承. 1. ...
- JavaScript进阶之路(一)初学者的开始
一:写在前面的问题和话 一个javascript初学者的进阶之路! 背景:3年后端(ASP.NET)工作经验,javascript水平一般般,前端水平一般般.学习资料:犀牛书. 如有误导,或者错误的地 ...
- JavaScript进阶(十一)JsJava2.0版本
JavaScript进阶(十一)JsJava2.0版本 2007年9月11日,JsJava团队发布了JsJava2.0版本,该版本不仅增加了许多新的类库,而且参照J2SE1.4,大量使用了类的继承和实 ...
- javascript进阶课程--第二章--对象
javascript进阶课程--第二章--对象 学习要点 理解面向对象的概念 掌握对象的创建方法 掌握继承的概念和实现方法 基本概念 对象究竟是什么?什么叫面向对象编程? 对象是从我们现实生活中抽象出 ...
- javascript进阶教程第二章对象案例实战
javascript进阶教程第二章对象案例实战 一.学习任务 通过几个案例练习回顾学过的知识 通过案例练习补充几个之前没有见到或者虽然讲过单是讲的不仔细的知识点. 二.具体实例 温馨提示 面向对象的知 ...
- JavaScript进阶知识点——函数和对象详解
JavaScript进阶知识点--函数和对象详解 我们在上期内容中学习了JavaScript的基本知识点,今天让我们更加深入地了解JavaScript JavaScript函数 JavaScript函 ...
- Javascript模拟继承(赠送.net吐槽一段)
首先吐槽一句,今年的就业形势很不乐观啊,特别是搞.net的(相对java),特特别是还没出校门没有正式工作经验的,找个实习很难,前些天接了个面试电话,上来就质疑我“你一个在校大学生怎么可能做了那么多项 ...
- 详解Javascript的继承实现(二)
上文<详解Javascript的继承实现>介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构 ...
随机推荐
- Globalization Guide for Oracle Applications Release 12
Section 1: Overview Section 2: Installing Section 3: Configuring Section 4: Maintaining Section 5: U ...
- iOS课程表
最近在做课程表,刚开始的时候完全不知道那个周课表的网格是怎么实现的有木有,各种查资料,寻思路,只找到一个安卓版的.没事,咱要的是思路而已.可能思路不是最优的,但还是总结一下,也希望能给其他人一点思路. ...
- pyqt5 动画在QThread线程中无法运行问题
自己做了一个tcp工具,在学习动画的时候踩了坑,需求是根据上线变绿色,离线变灰色,如果连接断开了,则变为灰色 问题现象: 可以看到点击"连接","离线"的时候动 ...
- Gulp基础知识
首先,我们需要了解Gulp能做些什么? 编译 sass sass是什么?(使CSS可以用编程的方式写,加快我们开发的速度) ...
- db2 查新索引 主键 sql
1.查询主键 select * from sysibm.syskeycoluse where tbname='...' 2.查询索引 select * from sysibm.indexs where ...
- 数据库面试题目- ORACLE
Posted on 2009-06-08 17:38 漠北的天空 阅读(110) 评论(0) 编辑 收藏 1. 列举几种表连接方式 Answer:等连接(内连接).非等连接.自连接.外连 ...
- Hibernate的二级缓存策略
Hibernate的二级缓存策略的一般过程如下: 1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次 ...
- HashMap 实现原理
深入Java集合学习系列:HashMap的实现原理 参考文献 引用文献:深入Java集合学习系列:HashMap的实现原理,大部分参考这篇博客,只对其中进行稍微修改 自己曾经写过的:Hashmap ...
- Mac 下实现 pyenv/virtualenv 与 Anaconda 的兼容
http://blog.csdn.net/vencent7/article/details/76849849 自己一直用的 pyenv 和 pyenv-virtualenv 管理不同的 python ...
- 一个resin启动bug的解决
这个bug的问题后来被确认为Resin所在目录层有中文目录名.--------------------------------------------------------------------- ...