探讨 JS 的面向对象中继承的那些事
最近学了 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 的面向对象中继承的那些事的更多相关文章
- JavaScript中继承的那些事
引言 JS是一门面向对象的语言,但是在JS中没有引入类的概念,之前特别疑惑在JS中继承的机制到底是怎样的,一直学了JS的继承这块后才恍然大悟,遂记之. 假如现在有一个“人类”的构造函数: functi ...
- 实用JS系列——面向对象中的类和继承
背景: 在最开始学习JavaScript时,我们就知道,它是一种脚本语言,也有面向对象机制.但它的面向对象继承机制是基于原型的,即Prototype.今天,我们就来找一下JS中OO的影子. 创建类 1 ...
- javascript面向对象中继承实现?
面向对象的基本特征有:封闭.继承.多态. 在javascript中实现继承的方法: 1.原型链(prototype chaining) 2.call()/apply() 3.混合方式(prototyp ...
- DotNet中的继承,剖析面向对象中继承的意义
继承是面向对象程序设计不可缺少的机制,有了继承这个东西,可以提高代码的重用,提高代码的效率,减轻代码员的负担. 面向对象三大特性:封装.继承.多态是相辅相成的.封装为了继承,限制了父类的哪些成员被子类 ...
- javascript面向对象中继承实现的几种方式
1.原型链继承: function teacher(name){ this.name = name; } teacher.prototype.sayName = function(){ alert(t ...
- JS中面向对象中的继承(常用写法)---核心部分
1.基本概念 子类继承父类,但是不能影响父类.包括1.混合继承(构造函数+原型) 2.ES6新增class的继承. 接下来介绍,面向对象中继承的两种常用写法.即混合继承(构造函数+原型)和class继 ...
- JavaScript面向对象(三)——继承与闭包、JS实现继承的三种方式
前 言 JRedu 在之前的两篇博客中,我们详细探讨了JavaScript OOP中的各种知识点(JS OOP基础与JS 中This指向详解 . 成员属性.静态属性.原型属性与JS原型链).今天 ...
- js中继承的几种用法总结(apply,call,prototype)
一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 <SPAN style="BACKGROUND-COLOR: #ffffff">& ...
- js中继承的方法总结(apply,call,prototype)
一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 代码如下: <SPAN style="<SPAN style="FONT-SIZE ...
随机推荐
- plsql developer 执行sql 文件
用 Command Window,执行 @'sql file path' 注意,上面sql文件路径要加单引号
- 根据经纬度反向地理编译出地址信息(如果报错:Error Domain=kCLErrorDomain Code=8 "(null)")
注意:Error Domain=kCLErrorDomain Code=8 "(null)" 如果出现这个错误 一定是 经纬度有问题 一定是 经纬度有问题 一定是 经纬度有问 ...
- Luogu P1955 [NOI2015]程序自动分析
又一次做了这道题,感慨万千. 记得寒假时,被cmd2001点起来讲这道题,胡言乱语..受尽鄙视(现在也是好吗)..后来下课想A掉,可是3天下来总是错...后来抄了分题解就咕咕了... 今天老师留了这道 ...
- 【OGG】OGG的单向DML复制配置(一)
[OGG]OGG的单向DML复制配置(一) 一.1 BLOG文档结构图 一.2 前言部分 一.2.1 导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识, ...
- 058 Length of Last Word 最后一个单词的长度
给定一个字符串, 包含大小写字母.空格 ' ',请返回其最后一个单词的长度.如果不存在最后一个单词,请返回 0 .注意事项:一个单词的界定是,由字母组成,但不包含任何的空格.案例:输入: " ...
- (转)使用参数SQL_SLAVE_SKIP_COUNTER处理mysql slave同步错误讨论
使用参数SQL_SLAVE_SKIP_COUNTER处理mysql slave同步错误讨论 本文链接地址:http://blog.chinaunix.net/uid-31396856-id-57532 ...
- 如何在windows下是用mysqldumpslow命令
1. 再一次点击mysql安装文件(默认是没安装mysqldumpslow这些脚本的),如图: 点击next如下图 点击Developer Components 旁边的选择this feature , ...
- 常用的http网页错误代码表---------495引发的一个简单到爆,但基于国内环境只能呵呵呵的血案
敲代码敲出了个网页错误代码 495. 然后,正常的跑去百度,看了一堆还是没有完整的网页错误代码,应该说国内的环境的网页错误代码表只有官方的那几个,那么只能FQ了. 去到谷歌,一查全是俄语,乐了,明白是 ...
- Java基础:(七)反射
一.什么是反射 理解反射之前,先要搞懂一件事情,类加载到底是怎么一回事? 类加载相当于Class对象的加载.每个类都有一个Class对象,包含了与类有关的信息.当编译一个新类时,会产生一个同名的.cl ...
- android pm命令
把网络apk下载到盒子或者其他安卓设备上 1.adb push windows的原路径 android设备的路径 2.pm install android设备的路径 注意:这里pm命令是安卓设备才有的 ...