js原型和原型链[转]
附上原文出处:http://hzjavaeyer.group.iteye.com/group/wiki/3086-JavaScript-core-concepts
一、概念:
原型对象:JavaScript对象是一个属性的集合,另外有一个隐式的对象:原型对象。原型的值可以是一个对象或者null。一般的引擎实现中,JS对象会包含若干个隐藏属性,对象的原型由这些隐藏属性之一引用,我们在本文中讨论时,将假定这个属性的名称为"__proto__"(事实上,SpiderMonkey内部正是使用了这个名称,但是规范中并未做要求,因此这个名称依赖于实现)。
原型链:由于原型对象本身也是对象,根据上边的定义,它也有自己的原型,而它自己的原型对象又可以有自己的原型,这样就组成了一条链,这个就是原型链,JavaScritp引擎在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefined.原型链一般实现为一个链表,这样就可以按照一定的顺序来查找。
二、实例:
No1:
var base = {
name : "base",
getInfo : function(){
return this.name;
}
} var ext1 = {
id : 0,
__proto__ : base
} var ext2 = {
id : 9,
__proto__ : base
} print(ext1.id);
print(ext1.getInfo());
print(ext2.id);
print(ext2.getInfo());
结果为:
0
base
9
base
图1:上例中对象的原型链
可以看到,当执行ext1.id时,引擎在ext1对象本身中就找到了id属性,因此返回其值0,当执行ext1.getInfo时,ext1对象中没有找到,因此在其原型对象base中查找,找到之后,执行这个函数,得到输出”base”。
我们将上例中的ext1对象稍加修改,为ext1对象加上name属性:
NO2:
var base = {
name : "base",
getInfo : function(){
return this.name;
}
} var ext1 = {
id : 0,
name : "ext1",
__proto__ : base
} print(ext1.id);
print(ext1.getInfo());
可以得到:
0
ext1
这个运行效果同样验证了原型链的运行机制:从对象本身出发,沿着__proto__查找,直到找到属性名称相同的值(没有找到,则返回undefined)。
我们对上例再做一点修改,来更好的演示原型链的工作方式:
NO3:
var base = {
name : "base",
getInfo : function(){
return this.id + ":" + this.name;
}
} var ext1 = {
id : 0,
__proto__ : base
} print(ext1.getInfo());
我们在getInfo函数中加入this.id,这个id在base对象中没有定义。同时,删掉了ext1对象中的name属性,执行结果如下:
0:base
应该注意的是,getInfo函数中的this表示原始的对象,而并非原型对象。上例中的id属性来自于ext1对象,而name来自于base对象。这个特性的机制在10.3小节再做讨论。如果对象没有显式的声明自己的”__proto__”属性,这个值默认的设置为Object.prototype,而Object.prototype的”__proto__”属性的值为”null”,标志着原型链的终结。
三、构造器:
我们在来讨论一下构造器,除了上边提到的直接操作对象的__proto__属性的指向以外,JavaScript还支持构造器形式的对象创建。构造器会自动的为新创建的对象设置原型对象,此时的原型对象通过构造器的prototype属性来引用。
我们以例子来说明,将Task函数作为构造器,然后创建两个实例task1, task2:
function Task(id){
this.id = id;
} Task.prototype.status = "STOPPED";
Task.prototype.execute = function(args){
return "execute task_"+this.id+"["+this.status+"]:"+args;
} var task1 = new Task(1);
var task2 = new Task(2); task1.status = "ACTIVE";
task2.status = "STARTING"; print(task1.execute("task1"));
print(task2.execute("task2"));
结果:
execute task_1[ACTIVE]:task1
execute task_2[STARTING]:task2
构造器会自动为task1,task2两个对象设置原型对象Task.prototype,这个对象被Task(在此最为构造器)的prototype属性引用,参看下图中的箭头指向。
图2:构造器方式的原型链
由于Task本身仍旧是函数,因此其”__proto__”属性为Function.prototype, 而内建的函数原型对象的”__proto__”属性则为Object.prototype对象。最后Obejct.prototype的”__proto__”值为null.
js原型和原型链[转]的更多相关文章
- Js 原型和原型链
Js中通过原型和原型链实现了继承 Js对象属性的访问,首先会查找自身是否拥有这个属性 如果查到,则返回属性值,如果找不到,就会遍历原型链,一层一层的查找,如果找到就会返回属性值 直到遍历完Object ...
- 【repost】JS原型与原型链终极详解
一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object ,Function 是JS自带的函数对象.下面举例说明 function f ...
- JS原型与原型链终极详解
一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object ,Function 是JS自带的函数对象.下面举例说明 function f ...
- JS原型与原型链终极详解(转)
JavaScript原型及原型链详解 一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object,Function 是JS自带的函数对象. ...
- 总结一下js的原型和原型链
最近学习了js的面向对象编程,原型和原型链这块是个难点,理解的不是很透彻,这里搜集了一些这方面的资料,以备复习所用 一. 原型与构造函数 Js所有的函数都有一个prototype属性,这个属性引用了一 ...
- JS原型和原型链
1 var decimalDigits = 2, 2 tax = 5; 3 4 function add(x, y) { 5 return x + y; 6 } 7 8 function su ...
- 深入JS原型与原型链
要了解原型和原型链,首先要理解普通对象和函数对象. 一.普通对象和函数对象的区别 在Javascript的世界里,全都是对象,而对象之间也是存在区别,我们首先区分一下普通对象和函数对象,如下代码: f ...
- JS对象、原型链
忘记在哪里看到过,有人说鉴别一个人是否 js 入门的标准就是看他有没有理解 js 原型,所以第一篇总结就从这里出发. 对象 JavaScript 是一种基于对象的编程语言,但它与一般面向对象的编程语言 ...
- JS面向对象之原型链
对象的原型链 只要是对象就有原型 原型也是对象 只要是对象就有原型, 并且原型也是对象, 因此只要定义了一个对象, 那么就可以找到他的原型, 如此反复, 就可以构成一个对象的序列, 这个结构就被成 ...
- JS 原型与原型链
图解: 一.普通对象 跟 函数对象 JavaScript 中,一切皆对象.但对象也有区别,分为 普通对象 跟 函数对象,Object 和 Function 是 JavaScript 自带的函数对象. ...
随机推荐
- .NET类库
1.如何让发布的C#的DLL类库中的方法带有注释说明 一个类库让第三方引用时,默认情况下生成类库时不携带注释,所以别人引用这个类库时就不是很方便理解类方法的作用和每个参数的含义,若是能携带方法的说明注 ...
- Django之tag标签和filter标签
1.Django的tag常见的标签,可以做一些简单的功能 {%if%} 的使用主要用于做判断,还可以包含{%elif%} 这样的用法,最后要跟上{% endif %}.可以使用你的and,or,not ...
- 基于jquery的可查询多级select控件(可记录历史选择)
一.功能和使用 公司有功能需求,还要一条代码引入的控件,网上找完全符合的控件比较难,寻找所花的时间还不如自己写一个,所以找个空闲时间自己写了一个 控件功能:1.可手动输入查询,也可点击下拉框查询, ...
- 你真的了解分层架构吗?——写给被PetShop"毒害"的朋友们
一叶障目 .NET平台上的分层架构(很多朋友称其为“三层架构”),似乎是一个长盛不衰的话题.经常看到许多朋友对其进行分析.探讨.辩论甚至是抨击.笔者在仔细阅读了大量这方面文章后,认为许多朋友在分层架构 ...
- 简明 Python 教程--学习记录
注意,我们在print语句的结尾使用了一个 逗号 来消除每个print语句自动打印的换行符.这样做有点难看,不过确实简单有效. print # prints a blank line 注意,没有返回值 ...
- Linux VPS禁止某个IP访问
http://www.vpser.net/security/linux-vps-deny-ip.html
- laravel的auth用户认证的例子
参考http://www.cnblogs.com/yjf512/p/4042356.html 需要注意的是,生成的测试数据,password部分必须用laravel自带的hash一下 Hash::ma ...
- linux(8)
第十九单元 nfs服务 ===============服务端 介绍: NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于198 ...
- Hadoop单机环境搭建整体流程
1. Ubuntu环境安装和基本配置 本例程中在MAC上安装使用的虚拟机Ubuntu系统(64位,desktop): 基本配置 考虑到以后涉及到hadoop的应用便于权限的管理,特别地创建一个ha ...
- 安装FreePBX的ISO版本
下载地址:http://schmoozecom.com/distro-download.php 这个相当于系统了,第一步:安装程序会提示选择你想安装Asterisk的版本:现在出现了11版本,这个根据 ...