原型链用于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. 关于js开发中保留小数位计算函数(以向上取整或向下取整的方式保留小数)

    前端工作中经常遇到数字计算保留小数问题,由于不是四舍五入的方式不能使用toFixed函数,本文采用正则表达式匹配字符串的方式,解决对数字的向上或向下保留小数问题: 1.向上保留小数(只要目标小数位后有 ...

  2. [luogu4478 BJWC2018] 上学路线 (容斥原理+拓展lucas)

    传送门 Description 小B 所在的城市的道路构成了一个方形网格,它的西南角为(0,0),东北角为(N,M). 小B 家住在西南角,学校在东北角.现在有T 个路口进行施工,小B 不能通过这些路 ...

  3. docker 容器操作( 以 tomcat 为例 )

    一.容器操作 一个镜像可以启动多个容器.比如一个 tomcat 镜像,可以启动多个tomcat 容器,启动后的这些 tomcat 都是各自独立的 二.步骤 1.搜索镜像 [root@localhost ...

  4. 暑假集训D14总结

    %dalao 今天dalao继续来讲课~讲的是一个叫kd树的奇怪东西= = 然而啥都没听懂 考试 今天多校联考,日常炸= = 照例打了前两道题的暴力(T1随便hash一下就水过了啊喂),然后开始推T3 ...

  5. 用saltapi远程操作tomcat启停时,输出日志乱码再解决

    以前解决过一次,是定义LC_ALL为指定编码.但这种思路不完全,因为机器各各不同,系统编码本身不一致(标准化之路漫长啊) 故而在其它一些系统的部署时,用上一次的方案,反而会有错误产生. 于是,按洪军找 ...

  6. android 点击返回键退出程序的方法

    android 点击返回键退出程序的方法 第一种: 再按一次返回键退出程序 private long exitTime = 0; @Override public boolean onKeyDown( ...

  7. 第一个关于selenium项目

    1.创建一个简单的Python工程 在主菜单中,选择File | New Project ,并指定Python解释器版本 2.创建python类,快捷键alt+insert 3.编写打开浏览器的代码, ...

  8. Linux实时查看日志,访问前10IP 和相关命令

    Nginx日志分析可以获得很多有用的信息,现在来试试最基本的,获取最多访问的前10个IP地址及访问次数. 既然是统计,那么awk是必不可少的,好用而高效. 命令如下: awk '{a[$1] += 1 ...

  9. CSS艺术之---负margin之美

    CSS中负边距(nagative margin)是布局中常常使用的一个技巧.仅仅要运用得当时常会产生奇异的效果.勘称CSS中的奇淫巧计,非常多CSS布局方法都依赖于负边距.掌握它对于前端童鞋来说还是非 ...

  10. 常用框架(一):spring+springMvc+mybatis+maven

    项目说明: (1) 本例采用 maven web 工程做例子讲解 (2) 利用mybaits 提供的代码生成工具自动生成代码(dao接口,sql mapper映射文件,pojo数据库映射类) (3) ...