最近学了 JS 的面向对象,这篇文章主要是探讨 JS 的面向对象中继承的那些事。

JS中继承的特点:

1、子类继承父类;

2、子类可以用父类的方法和属性

3、子类的改变可以不影响父类

下面用一个例子来说明 JS 的继承

这段代码创建了一个父类以及它的原型,同时还创建了一个子类,并继承了父类的私有属性

 <script>
//这是父类
function Father(name,age,marry){
this.name=name;
this.age=age;
this.marry=marry;
}
//父类的原型
Father.prototype.showName=function(){
alert(this.name);
} //子类
function Son(name,age,marry,weight){
Father.call(this,name,age,marry);
this.weight=weight;
} </script>

当子类Son想继承父类的原型时,我的做法一开始是这么做的

 <script>
//这是父类
function Father(name,age,marry){
this.name=name;
this.age=age;
this.marry=marry;
}
//父类的原型
Father.prototype.showName=function(){
alert(this.name);
} //子类
function Son(name,age,marry,weight){
Father.call(this,name,age,marry);
this.weight=weight;
} //错误的做法
Son.prototype=Father.prototype;
Son.prototype.showAge=function(){
alert(this.age);
}
var father=new Father('王大锤',30,true);
alert(father.showAge); </script>

运行的结果可以发现,子类原型的改变影响了父类的原型,父类的原型中本来是没有showAge方法的,这就违背了前面继承的第三个特点了。

分析原因:上面代码的第20行  Son.prototype=Father.prototype;这里的 '=' 两边都是对象,那么它代表的意思就是引用,如果是引用的话,左边的对象改变,肯定会影响了右边的对象

      所以才出现了子类原型的改变影响了父类的原型。

解决办法

方法一:核心思路,前面的问题不是说 '=' 是引用的关系才导致问题的嘛,那这里就保证 '=' 永远是赋值的关系,而不是引用。这里就定义一个 Clone() 方法,将父类对象拷贝给子类。

    Clone() 方法里用到递归的原因是,在拷贝的过程中对象中可能嵌套对象。

 <script>
//这是父类
function Father(name,age,marry){
this.name=name;
this.age=age;
this.marry=marry;
}
//父类的原型
Father.prototype.showName=function(){
alert(this.name);
} //子类
function Son(name,age,marry,weight){
Father.call(this,name,age,marry);
this.weight=weight;
}
Son.prototype=new Clone(Father.prototype);
Son.prototype.showAge=function(){
alert(this.age);
}
var father=new Father('王大锤',30,true);
alert(father.showAge); //通过克隆对象:核心思路是保证 '=' 是赋值的关系,而不是引用,也就是保证 '=' 的右边不是对象
function Clone(obj){
for(var i=0;i<obj.length;i++){
if(typeof(obj[key]=='object')){
this.key=new Clone(obj[key]);
}else{
this.key=obj[key];
}
}
}
</script>

这时候的结果父类对象的showAge方法是undefined

方法二:代码很简单,但是很难想到,没有第一个方法那么好理解。核心思想:对象自身属性的改变,不会影响其构造函数的属性的改变。

 <script>
//这是父类
function Father(name,age,marry){
this.name=name;
this.age=age;
this.marry=marry;
}
//父类的原型
Father.prototype.showName=function(){
alert(this.name);
} //子类
function Son(name,age,marry,weight){
Father.call(this,name,age,marry);
this.weight=weight;
}
function fn(){}
fn.prototype=Father.prototype;
Son.prototype=new fn();
Son.prototype.showAge=function(){
alert(this.age);
}
var father=new Father('王大锤',30,true);
alert(father.showAge); //通过克隆对象:核心思路是保证 '=' 是赋值的关系,而不是引用,也就是保证 '=' 的右边不是对象
// Son.prototype=new Clone(Father.prototype);
// function Clone(obj){
// for(var i=0;i<obj.length;i++){
// if(typeof(obj[key]=='object')){
// this.key=new Clone(obj[key]);
// }else{
// this.key=obj[key];
// }
// }
// }
</script>

探讨 JS 的面向对象中继承的那些事的更多相关文章

  1. JavaScript中继承的那些事

    引言 JS是一门面向对象的语言,但是在JS中没有引入类的概念,之前特别疑惑在JS中继承的机制到底是怎样的,一直学了JS的继承这块后才恍然大悟,遂记之. 假如现在有一个“人类”的构造函数: functi ...

  2. 实用JS系列——面向对象中的类和继承

    背景: 在最开始学习JavaScript时,我们就知道,它是一种脚本语言,也有面向对象机制.但它的面向对象继承机制是基于原型的,即Prototype.今天,我们就来找一下JS中OO的影子. 创建类 1 ...

  3. javascript面向对象中继承实现?

    面向对象的基本特征有:封闭.继承.多态. 在javascript中实现继承的方法: 1.原型链(prototype chaining) 2.call()/apply() 3.混合方式(prototyp ...

  4. DotNet中的继承,剖析面向对象中继承的意义

    继承是面向对象程序设计不可缺少的机制,有了继承这个东西,可以提高代码的重用,提高代码的效率,减轻代码员的负担. 面向对象三大特性:封装.继承.多态是相辅相成的.封装为了继承,限制了父类的哪些成员被子类 ...

  5. javascript面向对象中继承实现的几种方式

    1.原型链继承: function teacher(name){ this.name = name; } teacher.prototype.sayName = function(){ alert(t ...

  6. JS中面向对象中的继承(常用写法)---核心部分

    1.基本概念 子类继承父类,但是不能影响父类.包括1.混合继承(构造函数+原型) 2.ES6新增class的继承. 接下来介绍,面向对象中继承的两种常用写法.即混合继承(构造函数+原型)和class继 ...

  7. JavaScript面向对象(三)——继承与闭包、JS实现继承的三种方式

      前  言 JRedu 在之前的两篇博客中,我们详细探讨了JavaScript OOP中的各种知识点(JS OOP基础与JS 中This指向详解 . 成员属性.静态属性.原型属性与JS原型链).今天 ...

  8. js中继承的几种用法总结(apply,call,prototype)

    一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 <SPAN style="BACKGROUND-COLOR: #ffffff">& ...

  9. js中继承的方法总结(apply,call,prototype)

    一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 代码如下: <SPAN style="<SPAN style="FONT-SIZE ...

随机推荐

  1. plsql developer 执行sql 文件

    用 Command Window,执行 @'sql file path' 注意,上面sql文件路径要加单引号

  2. 根据经纬度反向地理编译出地址信息(如果报错:Error Domain=kCLErrorDomain Code=8 "(null)")

    注意:Error Domain=kCLErrorDomain Code=8 "(null)" 如果出现这个错误  一定是 经纬度有问题   一定是 经纬度有问题 一定是 经纬度有问 ...

  3. Luogu P1955 [NOI2015]程序自动分析

    又一次做了这道题,感慨万千. 记得寒假时,被cmd2001点起来讲这道题,胡言乱语..受尽鄙视(现在也是好吗)..后来下课想A掉,可是3天下来总是错...后来抄了分题解就咕咕了... 今天老师留了这道 ...

  4. 【OGG】OGG的单向DML复制配置(一)

    [OGG]OGG的单向DML复制配置(一) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识, ...

  5. 058 Length of Last Word 最后一个单词的长度

    给定一个字符串, 包含大小写字母.空格 ' ',请返回其最后一个单词的长度.如果不存在最后一个单词,请返回 0 .注意事项:一个单词的界定是,由字母组成,但不包含任何的空格.案例:输入: " ...

  6. (转)使用参数SQL_SLAVE_SKIP_COUNTER处理mysql slave同步错误讨论

    使用参数SQL_SLAVE_SKIP_COUNTER处理mysql slave同步错误讨论 本文链接地址:http://blog.chinaunix.net/uid-31396856-id-57532 ...

  7. 如何在windows下是用mysqldumpslow命令

    1. 再一次点击mysql安装文件(默认是没安装mysqldumpslow这些脚本的),如图: 点击next如下图 点击Developer Components 旁边的选择this feature , ...

  8. 常用的http网页错误代码表---------495引发的一个简单到爆,但基于国内环境只能呵呵呵的血案

    敲代码敲出了个网页错误代码 495. 然后,正常的跑去百度,看了一堆还是没有完整的网页错误代码,应该说国内的环境的网页错误代码表只有官方的那几个,那么只能FQ了. 去到谷歌,一查全是俄语,乐了,明白是 ...

  9. Java基础:(七)反射

    一.什么是反射 理解反射之前,先要搞懂一件事情,类加载到底是怎么一回事? 类加载相当于Class对象的加载.每个类都有一个Class对象,包含了与类有关的信息.当编译一个新类时,会产生一个同名的.cl ...

  10. android pm命令

    把网络apk下载到盒子或者其他安卓设备上 1.adb push windows的原路径 android设备的路径 2.pm install android设备的路径 注意:这里pm命令是安卓设备才有的 ...