这是关于原型链的一系列的现象与原理的解释以及例子 【转载请注明出处与地址】 分成4个部分阐述: 1.如何创建一个对象 2.使用原型链prototype实现对象的继承. 3.原型链上属性和方法的联系与规则 4.深入剖析原型链。 一、如何创建一个对象: 1.使用关键字new创建。 var obj=new Object; 或者 function c() {} var obj=new c(); 2.使用花括号创建。 var obj={}; 我们知道,function是定义一个函数,里面的var 都是局部变量,那么如何声明一个对象的属性和方法呢。秘密就在于this关键字。在函数内部使用this关键字,就相当于是对象的属性和方法的声明这个变量是存在的。具体的例子如下: function a() { this.a=1; this.get=function() { return this.a; } } 那么只要使用用var obj =new a();即创建一个对象的实例,里面就包括function里面的this属性和方法的就会直接拷贝到对象变量obj上。直接使用a.a的方法即可调用相应的属性和方法。 但是注意,除非实例化function a(),否则无法调用里面的this关键字指向的属性以及方法。 因为此时this上定义的属性以及方法类似于C++/JAVA等面向对象声明的属性以及方法。因此,这种定义函数的方法也被称为JS的构造函数。 二、使用原型链prototype实现对象的继承. 所有函数function都有一个默认的属性prototype,通过用typeof函数测试我们可以看到prototype是一个对象。 alert(typeof(a.prototype)); 结果: 那么这个prototype的属性到底有什么用呢~? 既然是一个对象那么赋值的时候就当然是付给prototype一个实例了。事实上,只要把一个实例赋给prototype这个属性,那么这个function就具有这个实例的属性和方法。相当于我们常说的继承。请看下面的代码: function a() { this.ia=1; this.get=function() { return this.ia; } } function b() //b构造函数 { this.ic=10; this.getfatherclass=function() { return this.ic; } } b.prototype=new a();//继承实例。 var obj =new b();//实例化函数b alert(obj.get()); 就是这么简单的逻辑,我们就是使用对象b实例化的obj,输出继承了父类a的方法get。输出父类a里面的属性ia。大家可以看到,这样就轻松地实现了继承。 那如果a又继承另外一个对象x怎么办? 答案当然是b会继承a所继承的所有东西。而他们的关系就像用prototype属性连起来一样。所以我们可以看成也是一个由prototype连接而成的链表,人称原型链。 三、原型链上属性和方法的联系与规则 首先我们明确一个概念,原型链就是一串好像用属性prototype连接而成的,每个节点具有属性和方法甚至函数过程的链。这种链式结构我们无疑可以发现一个很重要的问题----链上的节点之间发生属性或者方法重名怎么办?下面我们从读和写两方面来解析这条原型链的属性和方法的使用过程。 读: 从上面的例子里,alert(obj.get())输出的结果是什么呢,如果运行过一次,我们可以发现输出的结果是1. 但是我们可以看到,构造函数b定义的时候是没有get的方法的,同时,get方法调用的属性ia也是b中不存在的,那么我们在拥有prototype继承的构造函数所实例化的对象是如何调用属性和方法的呢。 结论是:对于调用实例化某一构造函数的对象的方法或者属性的时候,js会在原型链最结尾的点,也就是C++/JAVA上所描述的子类,上述例子中的b函数上,查找是否有所需要的方法或者属性,如果找不到的话,就会根据赋值给prototype的父节点对象,父构造函数上查找对应的属性和方法,就这样按照这种规则查找出对应名称的属性或方法。如果链上节点都不存在的话,当然就会输出undefined。 如果子节点有该属性或者方法,同时父节点也有的时候,当然会优先考虑子节点的,这也类似于C++/JAVA上所描述的覆盖的概念,子类的属性或者方法覆盖父类的。 而在上述例子中,get方法调用了一个this.ia,那么查找此此元素的时候,也会遵循上诉的原则,先查找构造函数b上是否有属性ia,没有的话再查找a上的构造函数上的属性ia。最后输出结果1。如果我们在构造函数b上添加一个属性this.ia=2,那么结果会如上述结论所说输出2. 写: 我们都知道,new操作会建立一个和构造函数一模一样的副本,开辟一个空间存放对象。但是我们从上面的操作可以看到,对于函数链上的属性,都可以被各个实例所访问,那么,js在实例化有prototype继承的构造函数的时候,是把链上的节点都实例化一次,还是被所有实例所共享呢?下面我们看下面例子。 function a() { this.ia=1; this.get=function() { return this.ia; } } function b() //b构造函数 { this.ic=10; this.getfatherclass=function() { return this.ic; } } b.prototype=new a();//继承实例。 var obj1 =new b();//实例化函数b var obj2 =new b();//实例化函数b alert(obj1.ia);//输出1,因为他是父类a中的ia alert(obj2.ia);//输出1,因为他是父类a中的ia obj1.ia=2; alert(obj1.ia);//输出2,因为写操作会在实例对象建立一个副本ia并且赋值2,无修改其原型链上的父节点。 alert(obj2.ia);//输出还是1,因为他是父类a中的ia b.prototype.ia=3;//修改原型链上的属性ia。 alert(obj1.ia);//输出2,因为已经在实例上建立了副本,所以优先读取副本。 alert(obj2.ia);//输出3,因为子类b中不存在,所以还是查找父节点(prototype对象上的对象)上的ia,由于父节点上的ia已经被修改成3,所以输出3. 上面的例子说明了2件事: 1.写操作并不是直接查找原型链上的属性,然后更改他,而是直接在实例上创建在一个同名对象。由于实例上已经存在这个属性,所以下次读取的时候优先读取这个已存在的,相当于原型链上的原属性被覆盖(但是还是存在的)。 2.Prototype链上的节点(父类)都是被子类实例化后的对象所共享,也就是只有唯一的一个对象prototype,因此当我们修改b.prototype.ia=3;/后,obj2输出的也是3,说明他是被其他没有创建ia属性副本的实例所共享的。 这样我们就清晰了,原型链只有一条,并且不会因为子类实例化和把链上的节点,属性与方法都实例化,他将被所有子类的实例化对象所共享。 而这个原型链上的父类是准读不准写(通过子类实例化对象改变链上节点的属性与方法)。一旦你的实例化对象进行和父类属性与方法同名的写操作时,就会在实例化对象上建立对应的副本,同时进行写操作,此时这个实例也覆盖了原型链上的这个属性和方法。这种方法很好的保护了原型链上节点的共享性,不用担心不小心被其他实例所修改。这样大大地节省了内存,可以在频繁的对象创建中,有效地减少了内存空间的使用。 当然可以通过函数b上的prototype对象来修改链上的属性与方法,这样就可以做到一改全改,让子类共享的属性发生改变。如上面的 b.prototype.ia=3;操作。 这种做法也衍生出一种叫做延时绑定的思想,在使用的时侯才进行属性和方法的绑定,这种行为是可以通过原型链、prototype这个属性实现的。这样可以很方便地应用到你的编程中,但是注意,这种方法还是弊大于利的,因为可以在任何地方进行重绑定。所以程序者也许不知道在何时进行了绑定,使得代码很混乱,同时在大代码量的情况下,照成不可预料的结果。因此,延时绑定必须慎用。 四、深入剖析原型链。 上面说到,原型链是由prototype连在一起的,事实上这种说法是不严谨,甚至可以说是错误的,因为prototype是一个对象,并且实例是没有prototype这个属性的,但是,有比prototype更好的,用来表现原型链的东西,这是对象实例后的一个私有属性,ie下是不可访问的,但是用firefox是可以查看的,它才是真正的作为实例在原型链上查找属性与方法的一个类似指针的属性。可以这么说,prototype是函数所有的,而__proto__是实例化的对象存在的属性。我们常把这个__proto__指向的原型成为父原型。因为prototype是一个对象的实例,所以原型也有父原型。下面给出一段例子来解释这个现象。 function a() { this.ia=1; this.get=function() { return this.ia; } } function b() //b构造函数 { this.ic=10; this.getfatherclass=function() { return this.ic; } } b.prototype=new a();//继承实例。 alert(a instanceof Function);//a是Function的实例; alert(a.__proto__ === Function.prototype);//a的父原型指向到Function的原型; alert(b.__proto__ === Function.prototype);//a的父原型指向到Function的原型 var obj =new b();//实例化函数b alert(typeof(obj.__proto__));//输出obejct,说明是一个对象 alert(obj instanceof Object);//ture.obj是其中一个对象 alert(obj.__proto__===b.prototype);//ture。因为__prototype指向父原型 alert(obj.__proto__.__proto__===a.prototype);//ture。因为__prototype指向父原型 alert(obj.__proto__.__proto__.__proto__===Object.prototype);//ture。因为__prototype指向父原型 alert(Object.prototype.__proto__);//null。因为Object的原型是所有父原型的顶端,它不再具有父原型; alert(Function instanceof Object);//Function是Object的实例; alert(Function.__proto__ === Function.prototype);//Function的父原型指向到Function的原型; alert(Function.prototype.__proto__ === Object.prototype);//Function的原型的父原型指向到Object的原型 alert(Object.__proto__ === Function.prototype);//Object的父原型指向到Function的原型; 从上面的例子我们再也清晰不过了,实例查找原型链的时候使用的__proto__ 这个私有属性,通过这个属性一层一层地遍历原型链,而原型链的最终父原型是Object.prototype,它是所有实例的父原型,只要修改这个父原型,那么所有的实例都将用到修改的属性。 同时。Function.prototype是所有函数的父原型,而它Function.prototype的父原型也是Object.prototype。到了这里,我们可以清晰地看到一个实例后面的原型链的全貌了。
Javascript原型链
转载于:https://www.cnblogs.com/si-ren/archive/2010/12/29/2447674.html
相关文章:

springbatch apache-activemq 整合(往mq中put数据,从mq中take数据)
简单测试如下:1:收下下载apache-activemq-5.14.4 解压apache-activemq-5.14.4\bin\win64,运行activemq.bat启动本地MQ服务器。通过浏览器可以查看本地MQ服务器的信息。http://127.0.0.1:8161/admin/index.jsp 2: 先往mq中put数据配置如下&…

什么是安全测试?哪些阶段需要安全测试?
安全测试是在IT软件产品的生命周期中,特别是产品开发基本完成到发布阶段,对产品进行检验以验证产品符合安全需求定义和产品质量标准的过程,可以说,安全测试贯穿于软件的整个生命周期。下面通过一张图描述软件生命周期各个阶段的安…

技术图文:如何利用C#爬取CSDN的博客文章?
背景 大家有没有这样的体验,在 CSDN 上发现某个博主有很多干货文章,我们就想拿到这个博主以往文章的列表,在需要的时候进行查询和浏览。 如果从 CSDN 网站上用复制粘贴的方式来建立这个列表,一个是工作量很大,另一个…

SAP BADI应用
SAP BADI应用 1.定义BADI 1) T-Code: SE18 Business Add-In Define. 2) 输入要创建的BADI的名字,点击"Create"。 3) 输入BADI的描述性文本,在"Interface"选项卡上输入接口的名字,也可以采用SAP建议的接口的…

为什么多 TCP 连接比单 TCP 连接传输快
转自: 我观察到,客户端机器从单一服务器使用 HTTP 下载一个文件:1. 单连接下载,速度没有达到客户端网络的最大带宽;2. 多连接同时下载,传输速度有极大的提高,带宽被占满。假设如下前提ÿ…

学Python的好处有哪些?
Python是一种比较简单的编程语言技术,想要快速进入到IT行业,Python是非常好的选择,为什么这么说呢?下面小编就为大家详细的介绍一下学Python的好处有哪些? 学Python的好处有哪些? 1.如果你是一名新媒体相关人员,学习Pyth…

技术图文:如何利用C# 实现 Kruskal 最小生成树算法?
背景 以前我写过一些图文来介绍有关数据结构与算法的知识: 8大排序算法之:直接插入排序(Straight Insertion Sort)8大排序算法之:希尔插入排序(Shell Insertion Sort)8大排序算法之࿱…

又偷懒了4个月,督促自己
又偷懒了4个月 每天浑浑噩噩,做着无聊简单的体力活,我不应该是这个追求撒!~~ 爸爸说的对,无论怎么样自己都要独立,要学习,爸爸希望我还去继续学习会计,我看下半年吧,各种学习都要&am…

java.lang.NoSuchMethodError: org.springframework.web.context.support.XmlWebApplicationContext.getEnv
转自:https://blog.csdn.net/u012941811/article/details/16960493 ava.lang.NoSuchMethodError: org.springframework.web.context.support.XmlWebApplicationContext.getEnvironment()Lorg/springframework/core/env/ConfigurableEnvironment; at 缺 org.springf…

零基础可以学好UI设计吗
随着UI设计行业的不断扩大发展,很多人都想要学习UI设计技术,但有很多同学都是零基础,想知道零基础可以学好UI设计吗?我们来看看下面的详细介绍就知道了。 零基础可以学好UI设计吗? 如果零基础自己学习UI设计着实有点吃力,毕竟对…

技术图文:如何利用C# 实现 Prim 最小生成树算法?
背景 我们上一篇图文介绍了 如何利用 C# 实现 Kruskal 最小生成树算法?,Kruskal 算法通过寻找边最优的方式来构造最小生成树,本篇图文介绍如何利用 C# 实现 Prim 最小生成树算法,Prim 算法通过寻找顶点最优的方式来构造最小生成树…

去除iphone图标的半弧高亮效果
只需要在info.plist里面添加一条记录UIPrerenderedIcon 新版的XCODE 会自动识别为Icon already includes gloss effects 打上勾就OK了 如果没有识别的右边栏写上YES就可以。转载于:https://www.cnblogs.com/jiewong/archive/2011/01/14/1935718.html

【短视频SDK - 参数解析】对焦模式、裁剪模式、视频质量、分辨率、视频比例、帧率、关键帧间隔等参数解析...
1.参数简析 参数名称简介影响裁剪模式分为填充模式和裁剪模式影响图像画面的展示细节视频质量是指生成的视频的输出参数,是一组参数决定的数值视频清晰度和文件大小分辨率图像分辨率则是单位英寸中所包含的像素点数,分辨率影响图像大小,与图像…

21年最新Python面试题及答案汇总详解(上)
错过三月找工作的机会,还要错过四月的好时期吗?Python面试你做准备了吗?下面小编整理了一套2021年最新Python常见面试题目,及Python面试题目答案汇总。希望能够帮助到大家。 21年最新Python面试题及答案汇总详解(上) 1、列表(list)和元组(tuple)有什么…

sina微博api源码阅读之函数
1. array_map将类的静态成员函数作为回调函数用在指定的单元上,可以递归调用 public static function urlencode_rfc3986($input) { if (is_array($input)) { return array_map(array(OAuthUtil, urlencode_rfc3986), $input); } else …

LeetCode实战:将有序数组转换为二叉搜索树
题目英文 Given an array where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by mo…

Spring、Spring Boot和TestNG测试指南 - @ActiveProfiles
Github地址 ActiveProfiles可以用来在测试的时候启用某些Profile的Bean。本章节的测试代码使用了下面的这个配置: Configuration public class Config {BeanProfile("dev")public Foo fooDev() {return new Foo("dev");}BeanProfile("prod…

python语言中如何使用注释
每一种计算机语言都有自己的注释方式,我们知道注释的作用是解释这些代码,方便程序员以后的检查和修改。而且注释的一部分在运行程序的过程中不起作用,也不会显示出来。下面我们将为大家介绍,在python语言中如何使用注释? 在pytho…

RHEL5(CentOS)下nginx+php+mysql+tomcat+memchached配置全过程(转)
RHEL5(CentOS)下nginxphpmysqltomcatmemchached配置全过程 一、准备工作: SSH,telnet终端中文显示乱码解决办法 vi /etc/sysconfig/i18n将内容改为 LANG"zh_CN.GB18030" LANGUAGE"zh_CN.GB18030:zh_CN.GB2312:zh_CN" SUPPORTED"zh_CN.GB18…

LeetCode实战:搜索二维矩阵
题目英文 Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties: Integers in each row are sorted from left to right.The first integer of each row is greater than the last integer of the previou…

windows指令
为什么80%的码农都做不了架构师?>>> C:\Windows\System32\drivers\etc nbtstat -a 1.7.2.2s 检查该IP的主机名称 WExNmU5Z windows启动配置界面 在“运行”中输入“msconfig mstsc -admin 远程 虚拟机的判断:如果有vmtoolsd.exe进程就是虚拟…

Java培训好不好?零基础可以学吗?
5g时代的来临,越来越多的人开启智能时代,互联网行业的发展速度越来越快,高薪行业一直受到很多人的关注,尤其是java这一块,很多人都想学习,那么参加Java培训好不好?零基础可以学吗? Java培训好不好?零基础…

顺水行舟,逆水行舟
水,或温柔,或猛烈 万物皆可比喻为水 顺水行舟,逆水行舟,皆为操船者智慧之体现 翻船者。。。把船搞翻了几回还执意而为,SB也。。。转载于:https://www.cnblogs.com/Zetazzz/archive/2011/01/30/1948082.html

LeetCode实战:二叉树的最大深度
题目英文 Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. Note: A leaf is a node with no children. Example: Given binary tree [3,9,20,null,n…

jfinal整合shiro回顾
2019独角兽企业重金招聘Python工程师标准>>> 目前jfinal使用shiro进行身份验证和授权的后台实现已完成,现在我再来总结下学习过程及代码实现过程。最近半年多项目开发都用.net,但又不甘心用了一年多的java,jfinal就这样被废弃&…

零基础学习Java培训有什么攻略
零基础学习Java培训有什么攻略?java是主流编程语言之一,我们在学习Java的时候需要制定Java学习路线图,Java涉及到的知识点非常的多,我们该从何学起呢?怎么系统的学习呢?来看看下面的详细介绍。 一、Java学习阶段 将Java学习过程分为3个阶段…

php去掉字符串的最后一个字符 substr()的用法
今天项目中用到,去掉字符串中的最后一个字符原字符串1,2,3,4,5,6,去掉最后一个字符",",最终结果为1,2,3,4,5,6代码如下:$str "1,2,3,4,5,6,"; $newstr substr($str,0,strlen($str)-1);echo $newstr;系统自带的函数也可…

如何加入LSGO软件技术团队?
背景 马上就要放暑假了! LSGO软件技术团队 也要开始招新了! 本次招入的同学,我会亲自来带,和你一起学习,共同成长。 我们的主要研究方向是机器学习,再详细一些就是视觉、自然语言处理和量化金融。 以下是…

《MySQL技术内幕:InnoDB存储引擎》读书笔记
2019独角兽企业重金招聘Python工程师标准>>> 1.InnoDB中每一页的大小默认为16kb,但是其也支持压缩页的功能,即将原本16kb的页压缩为1kb、2kb、4kb和8kb。当需要从缓存池中申请4kb大小的页时,MySQL的申请步骤如下: 检查…

UI设计要做什么,UI设计培训都要学什么
UI设计要做什么,UI设计培训都要学什么?相信有很多人都对这个问题比较感兴趣,近几年,UI设计被越来越多的人关注,行业薪资水平也是一路飙升,很多人都在准备学习UI设计,那么具体的内容,下面我们来…