原型链用于ECMAScript的继承。其思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。说人话,我们知道,一个构造函数Subtype,其原型对象有一个指向构造函数的指针,这是联系构造函数和原型的桥梁,如果我让原型对象的指针指向了另一个原型,而另一个原型原本指向其构造函数的指针也指向了另一个原型,那么,这就是一个原型链了,原型上的属性会一层一层往下传递。

function SuperType(){
this.property=true;
}
SuperType.prototype.getSuperValue=function(){
return this.property;
}; function SubType(){
this.subproperty=false;
}
//subtype继承了supertype的prototype
SubType.prototype=new SuperType();
SubType.prototype.getSubValue=function(){
return this.subproperty;
};
var instance=new Subtype();
alert(instance.getSuperValue());//true;

所以,继承的实现本质是重写了原型对象。

上面代码中,最后输出了true,原理是:以读取模式访问一个实例属性或方法,现在instance中搜索,搜索不到就沿着原型链往上查找,instance->Subtype.prototype->SuperType.prototype。如果找不到返回undefined.

在JS面向对象(1)中我们已经说到原型链的问题,也就是原型属性是可以被所有实例共享的。解决这个问题的方法可以是借用构造函数,JS高级程序设计上的解释是这种技术的基本思想是:在子类型构造函数的内部调用超类型的构造函数,函数是在特定环境中执行代码的对象,可以通过使用apply()和call()方法在新创建的对象上执行构造函数。这话说的我一愣一愣的0.0

 function SuperType(){
this.color=['aa','bb'];
} function SubType(){
SuperType.call(this);
}//继承了SuperType. var instance1=new SuperType();
var instance2=new SuperType();
instance1.color.push('cc');
alert(instance2.color)//['aa','bb'];没有因为instance1实例修改了color属性而被影响。

1、call可以扩充函数的作用域。

2、call可以传递参数。

第6行的SuperType.call(this),在new SubType时,即创建新对象时,同时执行SuperType构造函数,而且其中的this指向的是实例instance1或者instance2。因此每个实例都会有自己的colors副本。

call传递参数如下

function SuperType(name){
this.color=['aa','bb'];
this.name=name;
} function SubType(name){
SuperType.call(this,name);
this.age=20;
}//继承了SuperType. var instance1=new SubType('a');
var instance2=new SubType('b');
instance1.color.push('cc');
alert(instance2.color);//['aa','bb']
alert(instance2.age);//20
alert(instance2.name);//b;

组合继承 :使用原型链实现对原型属性和方法的继承(共享),使用构造函数实现对实例属性的继承(独立)。

function SuperType2(name){
this.name=name;
this.colors=['red','green'];
}
SuperType2.prototype.sayName=function(){
alert(this.name);//prototype的方法会共享给实例
};
function SubType2(name,age){
//继承属性
SuperType2.call(this,name);//借用超类型的构造函数 使每个subtype的实例拥有独立的colors副本,可以修改colors而不会影响其他实例的colors
this.age=age;
}
//继承方法
SubType2.prototype=new SuperType2();//SuperType2的实例赋值给SubType2原型
SubType2.prototype.constructor=SubType2;
SubType2.prototype.sayAge=function(){
alert(this.age);
};
/*SubType2.prototype={
sayAge:function(){
alert(this.age);
}
};*/ var instance3=new SubType2('nick',20);
var instance4=new SubType2('jack',30);
instance3.colors.push('black');
alert('组合继承 age:'+instance3.age);//
alert('instance3自己修改后的的colors:'+instance3.colors);//['red','green','black'];
alert(instance3.name);//nick
instance3.sayName();//nick
instance3.sayAge();//20
instance4.sayName();//jack
instance4.sayAge();//30

SuperType2的实例赋值给SubType2原型,两个不同的instance3和instance4实例拥有自己的属性,name/color/age等,还可以有相同的方法sayAge() sayName()。

组合继承是最常用的继承模式,除此之外还有许多的模式,如原型式继承、寄生式继承等。

JS面向对象(2)——原型链的更多相关文章

  1. JS面向对象之原型链

      对象的原型链 只要是对象就有原型 原型也是对象 只要是对象就有原型, 并且原型也是对象, 因此只要定义了一个对象, 那么就可以找到他的原型, 如此反复, 就可以构成一个对象的序列, 这个结构就被成 ...

  2. js继承之原型链继承

    面向对象编程都会涉及到继承这个概念,JS中实现继承的方式主要是通过原型链的方法. 一.构造函数.原型与实例之间的关系 每创建一个函数,该函数就会自动带有一个 prototype 属性.该属性是个指针, ...

  3. JS对象、原型链

    忘记在哪里看到过,有人说鉴别一个人是否 js 入门的标准就是看他有没有理解 js 原型,所以第一篇总结就从这里出发. 对象 JavaScript 是一种基于对象的编程语言,但它与一般面向对象的编程语言 ...

  4. JS中的原型链和原型的认识

    这篇文章主要是学习一下JavaScript中的难点------原型和原型链 自定义一个对象 我们学习一门编程语言,必然要使用它完成一些特定的功能,而面向对象的语言因为符合人类的认知规律,在这方面做得很 ...

  5. JS面向对象,原型,继承

    ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,ECMAScript ...

  6. js面向对象与原型

    创建对象 var box = new Object();//创建对象 box.name = 'Lee'; //添加属性 box.age = 100; box.run = function(){ ret ...

  7. JS中注意原型链的“指向”

    昨天压缩Js文件时发现了项目中的一个prototype的问题代码如下所示: 1. <script> var XXX = function(){ }; var x1 = new XXX(); ...

  8. JS 一条原型链扯到底

    在正文之前,首先要知道两点, 1.__proto__是每个js 对象的内置属性,而prototype 是函数的内置属性,也是一个对象. 2.所谓原型,指的就是每个函数对象的prototype属性. f ...

  9. 深入理解JS对象和原型链

    函数在整个js中是最复杂也是最重要的知识 一个函数中存在多面性: 1.它本身就是一个普通的函数,执行的时候形成的私有作用域(闭包),形参赋值,预解释,代码执行,执行完 成后栈内存销毁/不销毁. 2.& ...

  10. JS面向对象之原型

    面向对象之原型 为什么要使用原型 由于 js 是解释执行的语言, 那么在代码中出现的函数与对象, 如果重复执行, 那么会创建多个副本, 消耗更多的内存, 从而降低性能 传统构造函数的问题 functi ...

随机推荐

  1. Python基础练级攻略:day01

    如果你有足够长时间做某事,一定会更擅长. 知识点: 计算机基础 变量 运算符 if语句 for-in循环 函数 列表.元组.字典.字符串.集合 ascii.unicode.utf-8.gbk 区别 A ...

  2. 【Leetcode】【简单】【14最长公共前缀】【JavaScript】

    题目 14. 最长公共前缀 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower",& ...

  3. 51nod1134 最长递增子序列【动态规划】

    给出长度为N的数组,找出这个数组的最长递增子序列.(递增子序列是指,子序列的元素是递增的) 例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10. Input 第1行:1个数N ...

  4. CSS font-style中italic和Oblique有何区别 标签: css字体 2017-01-05 14:42 60人阅读 评论

    *要搞清楚这个问题,首先要明白字体是怎么回事.一种字体有粗体.斜体.下划线.删除线等诸多属性. 但是并不是所有字体都做了这些,一些不常用的字体,或许就只有个正常体,如果你用Italic,就没有效果了~ ...

  5. 还不打算去认识一下webpack?

    前言 随我来,去看看webpack!(为时未晚)============>第一版(较浅显的知识,懂得可忽略本文) 方向 安装,起步搭建运行. (粗略代过) 对于资源的管理,对于输出的管理. (举 ...

  6. 【ABCD组】Scrum meeting 4

    前言 第4次会议在6月16日由组长在教9 405召开. 主要对下一步的工作进行说明安排,时长90min. 主要内容 分配下阶段任务,争取在这阶段完成软件的设计阶段 任务分配 姓名 当前阶段任务 贡献时 ...

  7. GOF23设计模式之适配器模式

    GOF23设计模式之适配器模式 结构型模式: 核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题. 分类:适配器模式.代理模式.桥接模式.装饰模式.组合模式.外观模式. ...

  8. Spring Boot-全局异常处理(八)

    SpringBoot默认异常默认处理机制 Spring boot错误异常时通过BasicErrorController来处理的 通过判断是浏览器请求还是ajax请求响应页面或者json BasicEr ...

  9. rmq算法,利用倍增思想

    RMQ问题ST算法  /*  RMQ(Range Minimum/Maximum Query)问题:      RMQ问题是求给定区间中的最值问题.当然,最简单的算法是O(n)的,但是对于查询次数很多 ...

  10. mysql 与elasticsearch实时同步常用插件及优缺点对比(ES与关系型数据库同步)

    前言: 目前mysql与elasticsearch常用的同步机制大多是基于插件实现的,常用的插件包括:elasticsearch-jdbc, elasticsearch-river-MySQL , g ...