附上原文出处: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原型和原型链[转]的更多相关文章

  1. Js 原型和原型链

    Js中通过原型和原型链实现了继承 Js对象属性的访问,首先会查找自身是否拥有这个属性 如果查到,则返回属性值,如果找不到,就会遍历原型链,一层一层的查找,如果找到就会返回属性值 直到遍历完Object ...

  2. 【repost】JS原型与原型链终极详解

    一. 普通对象与函数对象  JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object ,Function 是JS自带的函数对象.下面举例说明 function f ...

  3. JS原型与原型链终极详解

    一. 普通对象与函数对象  JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object ,Function 是JS自带的函数对象.下面举例说明 function f ...

  4. JS原型与原型链终极详解(转)

    JavaScript原型及原型链详解 一. 普通对象与函数对象 JavaScript 中,万物皆对象!但对象也是有区别的.分为普通对象和函数对象,Object,Function 是JS自带的函数对象. ...

  5. 总结一下js的原型和原型链

    最近学习了js的面向对象编程,原型和原型链这块是个难点,理解的不是很透彻,这里搜集了一些这方面的资料,以备复习所用 一. 原型与构造函数 Js所有的函数都有一个prototype属性,这个属性引用了一 ...

  6. JS原型和原型链

        1 var decimalDigits = 2, 2 tax = 5; 3 4 function add(x, y) { 5 return x + y; 6 } 7 8 function su ...

  7. 深入JS原型与原型链

    要了解原型和原型链,首先要理解普通对象和函数对象. 一.普通对象和函数对象的区别 在Javascript的世界里,全都是对象,而对象之间也是存在区别,我们首先区分一下普通对象和函数对象,如下代码: f ...

  8. JS对象、原型链

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

  9. JS面向对象之原型链

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

  10. JS 原型与原型链

    图解: 一.普通对象 跟 函数对象 JavaScript 中,一切皆对象.但对象也有区别,分为 普通对象 跟 函数对象,Object 和 Function 是 JavaScript 自带的函数对象. ...

随机推荐

  1. CentOS 7.0 yum安装Apache、PHP和MySQL

    centos7默认将mariadb视作mysql. p.s.因为mysql被oracle收购后,原作者担心mysql闭源,所以又写了一个mariadb,这个数据库可以理解为mysql的分支. 卸载ma ...

  2. Android学习路线总结,绝对干货(转)

    title: Android学习路线总结,绝对干货tags: Android学习路线,Android学习资料,怎么学习androidgrammar_cjkRuby: true--- 一.前言 不知不觉 ...

  3. WebSocket的使用

    WebSocket是长连接,如果客户端的程序没有数据实时同步的需求就没必要使用它.因为长连接会带来一定的服务器内存开销.如果Ajax就能轻松搞定的话就完全没必要兴师动众的搞WebSocket. htt ...

  4. psd文件导出为图片教程

    美术给过来PSD文件好多层啊.怎么挨个把需要的图片导出来呢. 1. 选中 要导出的图片的图层 2.ctrl+N 新建个文档  然后把图片拉到 新的里面 然后点图像-裁剪 确定就行了,然后ctrl+s保 ...

  5. Promise的一些相关讲解

    在javascrpit的语言特性上 有明确的一个特性指出,该语言的是单线程进程.这就意味着JavaScript的所有网络操作,浏览器事件,都必须是异步执行. 如下面的例子,可以感受到单线程与异步回调: ...

  6. 西南大学网络实现路由器WIFI共享方案(一号多用户共享)

    背景: 学校更换网页认证,限制多台设备的登录,后台记录发现会将账号封30min禁止登陆,于是想办法冲破这个限制.看到马丁大神的博客知道了学校的检测机制,只需要定时对账号进行认证下线即可实现,不被学校检 ...

  7. cowboy的中间件

    想不到cowboy这样的,居然也有中间件的概念,膜拜作者 创建工程 rebar-creator create-app testCowboy testCowboy_app.erl -module(tes ...

  8. 实现 Win32 程序的消息映射宏(类似 MFC )

    对于消息映射宏,不用多说了,用过 MFC 的人都很清楚.但目前有不少程序由于各种原因并没有使用 MFC,所以本帖讨论一下如何在 Win32 程序中实现类似MFC的消息映射宏.其实 Windows 的头 ...

  9. java web 程序--注册页面/HashMap的用法。。要懂啊

    思路:1.一个form表单,用户输入后,提交 2.第二个是注册页面,主要是用Map.先假设往map里面拿东西,然后判断是否为空  若为空,new 一个HashMap它的子类,然后通过map.conta ...

  10. java代码---实现随机产生1000个随机数,并10个一行的输出

    总结:不会用,就是不熟 package com.s.x; //输入10个随机数,并显示最大值,最小值 import java.util.*; public class Value { public s ...