在javascript里面看到javascript的继承模式和传统的继承模式是有区别的,就想查资料看一下到底有区别,就看到了这篇文章,觉得讲得还可以,暂时先放上来,以后有别的东西再补充:

http://segmentfault.com/a/1190000000766541

基本模式

var Parent = function(){
this.name = 'parent';
};
Parent.prototype.getName = function(){
return this.name;
};
Parent.prototype.obj = {a:1}; var Child = function(){
this.name = 'child';
}
Child.protytype = new Parent(); var parent = new Parent();
var child = new Child(); console.log(parent.getName());//parent
console.log(child.getName());//child

这种事最简单实现原型继承的方法,直接把父类的对象复制给子类的构造函数的原型,这样子类的对象就可以访问到父类以及父类构造函数的protytype



这种方法的优点就是实现起来比较简单,不需要任何特殊的操作;同时他的缺点也很明显,如果子类需要做跟父类构造函数中相同的初始化动作,那么就得在子类构造函数中再重复一遍父类中的操作:

var Parent = function(name){
this.name = name || 'parent';
};
Parent.prototype.getName = function(){
return this.name;
};
Parent.prototype.obj = {a:1}; var Child = function(name)
{
this.name = name || 'child';
};
Child.prototype = new Parent(); var parent = new Parent('myParent');
var child = new Child('myChild'); console.log(parent.getName());//myParent
console.log(child.getName());//myChild

上述还只是初始化name属性,如果初始化工作不断增加,这种方式也不是很方便。

借用构造函数

var Parent = function(name){
this.name = name || 'parent';
};
Parent.prototype.getName = function(){
return this.name;
}
Parent.prototype.obj = {a:1}; var Child = function(name){
Parent.apply(this,arguments);
}
Child.prototype = new Parent(); var parent = new Parent('myParent');
var child = new Child('myChild'); console.log(parent.getNmae());//myParent
console.log(child.getName());//myChild

上面这种方法在子类构造函数中通过apply调用父类的构造函数进行相同的的初始化工作,这样不管负累做了多少初始化工作,子类可以执行同样的初始化工作。但是上面这种实现方法存在一个问题,父类构造函数被执行了两次,一次是在子类构造函数中,椅子是在赋值子类原型的时候,这是多余的,我们可以做以下改进:

var Parent = function(name){
this.name = name || 'parent';
};
Parent.prototypr.getName = function(){
return this.name;
};
Parent.prototype.obj = {a:1}; var Child = function(name){
Parent.apply(this,arguments);
};
Child.protytype = Parent.protytype; var parent = new Parent('myParent')
var child = new Child('myChild'); console.log(parent.getName());//myParent
console.log(child.getName());//myChild

这样我们只需要在子类构造函数中执行一次父类的构造函数,同时又可以继承父类原型中的属性,这也比较原型的初衷,就是吧需要复用的内容放在原型中,我们可以继承原型中可复用的内容

临时构造函数模式

上面借用构造函数模式还是存在问题,它把父类的原型直接赋值给子类的原型,这会造成一个问题,就是如果对子类的原型做了修改,那么这个修改同时也会影响到父类的原型,进而影响父类对象。

var Parent = function(name){
this.name = name || 'parent';
};
Parent.prototype.getName = function(){
return this.name;
};
Parent.prototype.obj = {a:1}; var Child = function(name){
Parent.apply(this,arguments);
};
var F = new function(){};
F.prototype = Parent.prototype;
Child.prototype = new F(); var parent = new Parent('myParent');
var child = new Child('myChild'); console.log(parent.getName());//myParent
console.log(child.getName());/myChild

这样做事在子类原型和父类原型之间加入一个临时的构造函数F,切断了子类原型和父类原型之间的联系,这样子类原型的修改就不会影响到父类原型。

继续讨论

上面可以刻到的我们在Parent的prototype属性中加入一个obj对象字面量属性,但是一直没有使用

var Parent = function(name){
this.name = name || 'parent';
};
Parent.prototype.getName = function(){
return this.name;
};
Parent.prototype.obj = {a:1}; var Child = function(name){
Parent.aplly(this,arguments);
};
var F = new function(){};
F.prototype = Parent.prototype;
Child.prototype = new F(); var parent = new Parent('myParent');
var child = new Child('myChild'); console.log(child.obj.a);//1
console.log(parent.obj.a);//1
child.obj.a = 2;
console.log(child.obj.a);//2
console.log(parent.obj.a);//2

在上面这种情况,当我们把child对象obj.a修改的时候,同时父类的原型中的obj.a也会被修改。原因是因为当访问child.obj.a的时候,我们会沿着原型链一直找到父类的prototype中,然后找到了obj属性,然后对obj.a进行修改.

var Parent = function(name){
this.name = name || 'parent';
};
Parent.prototype.getName = function(){
return this.name;
};
Parent.prototype.obj = {a:1}; var Child = function(name){
Parent.aplly(this,arguments);
};
var F = new function(){};
F.prototype = Parent.prototype;
Child.prototype = new F(); var parent = new Parent('myParent');
var child = new Child('myChild'); console.log(child.obj.a);//1
console.log(parent.obj.a);//1
child.obj.a = 2;
console.log(child.obj.a);//2
console.log(parent.obj.a);//2

javascript的继承模式的更多相关文章

  1. 一文详解JavaScript的继承模式

    1 原型链继承 #### ES6中通过原型继承多个引用类型的属性和方法,由于原型和实例的关系,即每个构造函数都有自己的原型对象,同时原型有一个属性指向构造函数,并且实例有一个内部的指针指向原型.如果存 ...

  2. 【读书笔记】读《JavaScript模式》 - 函数复用模式之现代继承模式

    现代继承模式可表述为:其他任何不需要以类的方式考虑得模式. 现代继承方式#1 —— 原型继承之无类继承模式 function object(o) { function F() {}; F.protot ...

  3. 【读书笔记】读《JavaScript模式》 - 函数复用模式之类式继承模式

    实现类式继承的目标是通过构造函数Child()获取来自于另外一个构造函数Parent()的属性,从而创建对象. 1.类式继承模式#1 —— 默认方式(原型指向父函数实例) function Paren ...

  4. 浅谈 JavaScript 中的继承模式

    最近在读一本设计模式的书,书中的开头部分就讲了一下 JavaScript 中的继承,阅读之后写下了这篇博客作为笔记.毕竟好记性不如烂笔头. JavaScript 是一门面向对象的语言,但是 ES6 之 ...

  5. JavaScript的7种继承模式

    <JavaScript模式>一书中,对于JavaScript的几种继承模式讲解得很清楚,给我提供了很大帮助.总结一下,有如下7种模式. 继承模式1--设置原型(默认模式) 实现方式: // ...

  6. javascript类式继承模式#4——共享原型

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. javascript类式继承模式#3——借用和设置原型

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. javascript类式继承模式#2——借用构造函数

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. javascript类式继承模式#1——默认模式

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. windows 2003 系统管理员debug

  2. 简单生成随机数id的方法

    近期项目中需要生成不同的id,之前都是使用UUID来实现的,现在需求是只要8位数的,也就是说用户量是有限的,暂时是不需要太多的,所以就简单的使用Set实现了这一功能. /** * 生成8位不重复随机i ...

  3. Flutter-網絡請求

    Flutter 请求网络的三种方式 flutter 请求网络的方式有三种,分别是 Dart 原生的网络请求 HttpClient.第三方网络请求 http以及 Flutter 中的 Dio.我们可以比 ...

  4. 关于BFC的总结

    虽然工作这么多年了,但是如果让我直接解释一下什么是BFC的时候,还是感觉有点不知道怎么准确的表达,下面就翻翻文档,总结一下,加深一下认识吧.大家也可以关注我的GitHub后续的更新 1.BFC的基本概 ...

  5. 爬虫技术:数据处理josn和pickle模块

    一:json模块 json模块的作用就是讲json字符串("{"a":1,"b":1}")和python能够识别的字典进行相互转换. imp ...

  6. 对微信小程序的研究2

    .json 后缀的 JSON 配置文件 .wxml 后缀的 WXML 模板文件 .wxss 后缀的 WXSS 样式文件 .js 后缀的 JS 脚本逻辑文件 JSON 配置 我们可以看到在项目的根目录有 ...

  7. macOS 10.14 Mojave Apache Setup: Multiple PHP Versions

    Part 1: macOS 10.14 Mojave Web Development Environment Developing web applications on macOS is a rea ...

  8. java logger的info记录在哪

    这个要看你的日志配置文件是怎么配置的,以log4j为例log4j.appender.mainLog=org.apache.log4j.ConsoleAppenderlog4j.appender.mai ...

  9. python 虚拟机是单线程;当线程执行I/O密集型操作是,ce

    python 虚拟机是单线程:当线程执行I/O密集型操作是 单核CPU,不存在“并行”,与语言无关:每个线程运行中,其他线程等待该线程让步 粗粒度的并行 靠 软件,细---硬---

  10. 移动端调试 — chrome模拟器基础调试

    打开开发者工具,进入chrome调试状态,点击左上角的手机图标,进入手机模拟器调试状态. 模拟器支持操作: 切换设备类型,模拟网络环境,模拟bar,keyboard弹出状态,横屏状态,更改UserAg ...