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 自带的函数对象. ...
随机推荐
- VMware harbor && minio 搭建企业docker私有镜像以及需要注意的问题
1. docker harbor 配置 建议使用在线安装的模式(离线包太大了) 首先需要安装docker-compose .docker .mino (具体安装可以参考官网后者我的博 ...
- nginx fastcgi 优化
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m; fastcgi ...
- .NET平台上的Model-View-Presenter模式实践
为什么要写这篇文章 笔者当前正在负责研究所中一个项目,这个项目基于.NET平台,初步拟采用C/S部署体系,所以选择了Windows Forms作为其UI.经过几此迭代,我们发现了一个问题:虽然业务逻辑 ...
- git还原某个特定的文件到之前的版本
场景: 对于某个git控制下的文件进行了修改,但是改的不满意,想退回到改之前的版本.假定该文件为 src/main/main.c 解决方法: 第一步: 在命令行中输入 git log src/main ...
- JavaScript模块化-require.js,r.js和打包发布
在JavaScript模块化和闭包和JavaScript-Module-Pattern-In-Depth这两篇文章中,提到了模块化的基本思想,但是在实际项目中模块化和项目人员的分工,组建化开发,打包发 ...
- MEF学习总结(2)---Primitive层
Primitive层是属于依赖注入的通用模型,主要有如下核心类型: 1. ComposablePart是核心类,他表示组件容器中的每一个组件,是对真正组件实例的包装.ExportDefinition属 ...
- RK3288 HDMI增加特殊分辨率
转载请注明出处:https://www.cnblogs.com/lialong1st/p/9174475.html CPU:RK3288 系统:Android 5.1 本帖以 HDMI 800x600 ...
- 编译openvpn在链接时报tuncfg错误
1. 链接时产生tuncfg错误 init.o: In function `do_persist_tuntap': init.c:(.text+0x24d8): undefined reference ...
- php端安装rabbitmq-c
php端安装rabbitmq-c url:https://github.com/alanxz/rabbitmq-c cd rabbitmq-c**** ./configure --prefix=/us ...
- appium在android7.0上无法启动问题
前言 由于最近很多android手机升级到7.0系统了,有些小伙伴的appium版本用的还是1.4版本,在运行android7.0的app自动化时候遇到无法启动问题:WebDriverExceptio ...