原型继承的本质就是一条原型链,对象会沿着这条链,访问链里的方法属性.

对象的__proto__属性就是用于访问它的原型链的上一层:

考虑以下对象:

1. 所有对象的原型:

Object.prototype

2. 所有函数的原型:

Function.ptototype

3. 函数的构造函数:

Function

4. 对象的构造函数:

Object

5. 自定义的构造函数Person:

function Person(){

this.name=function(){};

this.init=function(){alert('我是Person对象的方法')};

}

6. 自定义构造函数Person的原型Person.prototype:

Person.prototype.init=function(){alert('我是Person原型的方法')}

7. 通过Person实例化得到的对象person:

var person = new Person();

person.init=function(){alert('我是person私有的方法')}

8. 通过Object实例化得到的对象object:

var object = new Object();

* 注意: var object = {},一样也是通过Object实例化得到的对象

他们之间的继承关系如下:

从最外层的开始看起,如果要访问person实例的某个方法属性,它寻找的顺序应该是这样的:

完整代码:

Object.prototype.init=function(){alert('我是对象的原型的方法')};

function Person(){

     this.name=function(){};

     this.init=function(){alert('我是Person对象的方法')};

}

Person.prototype.init=function(){alert('我是Person原型的方法')}

var person = new Person();

person.init=function(){alert('我是person私有的方法')}

var object = new Object();

person.init();

首先寻找person的私有方法:

--也就是这里的person.init;

如果找不到,会找到Person的对象的方法:

--也就是这里的Person构造函数里的的this.init;

如果再找不到,它就会到原型链里去找方法:

person的原型链,就是person.__proto__,这里就是指向Person.prototype

因为,顺着原型链,首先会找到Person原型的方法:

--也就是这里的Person.prototype.init;

如果再找不到,它会顺着原型链继续找,也就是Person.prototype.__proto__,就是指向Object.prototype

--也就是这里的Object.prototype.init;

如果再找不到,那么就没有了,因为Object.prototype.__proto__指向null

所以,在js里,一切皆对象,因为所有的对象通过原型链,最后都会继承Object.prototype里的方法和属性,比如toString...等等...

再来看Person构造函数,Function构造函数,Object构造函数:

这三个都属于构造函数对象,通过他们可以new 一个对象,他们本身的__proto__都是Function.prototype,所以他们都继承了Function所有用的方法,比如bind(),apply()...等...

同样,示例中虽然没有提到,但是相似的,所有的内置构造函数,他们的__proto__也都是Function.prototype:

Boolean.__proto__ === Function.prototype // true
String.__proto__ === Function.prototype // true
Object.__proto__ === Function.prototype // true
Function.__proto__ === Function.prototype // true
Array.__proto__ === Function.prototype // true
RegExp.__proto__ === Function.prototype // true
Error.__proto__ === Function.prototype // true
Date.__proto__ === Function.prototype // true
 
Math对象和JSON对象,不是构造函数,他们的__prototype__是Object.prototype:
Math.__proto__ === Object.prototype  // true
JSON.__proto__ === Object.prototype // true

至于constructor,具体查阅上一篇文章:

http://www.cnblogs.com/liulangmao/p/3467863.html

javascript高级:原型与继承的更多相关文章

  1. 【面试必备】javascript的原型和继承

    原型.闭包.作用域等知识可以说是js中面试必考的东西,通过你理解的深度也就能衡量出你基本功是否扎实.今天来复习一下javascript的原型和继承,虽说是老生常谈的话题,但对于这些知识,自己亲手写一遍 ...

  2. JavaScript高级特性-实现继承的七种方式

    声明和约定: 在C++和Java中,我们可以通过关键字class来声明一个类,在JavaScript中没有这个关键字,但我们知道可以通过new一个function创建对象,这个function类似C+ ...

  3. 深入浅出JavaScript之原型链&继承

    Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instanc ...

  4. javascript的原型和继承(1)

    原型与继承是javascript中基础,重要而相对比较晦涩难解的内容.在图灵的网上看到一篇翻译过的文章,有参考了一些知名博客.我自己总结了几篇.通过这次的总结,感觉自己对原型和继承的认识又增加了很多, ...

  5. JavaScript的原型链继承__propt__、prototype、constructor的理解、以及他们之间相互的关系。

    回想自己已经工作了有一段时间了,但是自己对JavaScript的原型链.和继承的理解能力没有到位,最近他们彻底的整理并且复习了一遍. 本案例中部分文案来自网络和书籍,如有侵权请联系我,我只是把我的理解 ...

  6. JavaScript 面向对象 原型(prototype) 继承

    1.对象的概念:无需属性的集合,属性可以为数值,对象或函数,ECMAscript中没有类的概念,这点是javascript与其他面向对象(OO)语言不同的地方. //创建一个自定义对象 var per ...

  7. javascript 高级编程系列 - 继承

    1. 原型链继承 (缺点:子类继承父类的引用类型的属性值会在各个实例中共享,创建子类实例时无法向父类构造函数传递参数) // 定义父类构造函数 function SuperClass(father, ...

  8. JavaScript基于原型的继承

    在一个纯粹的原型模式中,我们会摒弃类,转而专注于对象,基于原型的继承相比基于类的继承的概念上更为简单 if( typeof Object.beget !== 'function') { Object. ...

  9. javascript的原型与继承(2)

    这是上一篇的后续. Javascript是一种基于对象的语言,遇到的所有东西几乎都是对象.如果我们想要把属性和方法封装成一个对象,应该怎么做呢: 假设我们把猫看成一个对象: var Cat = { n ...

随机推荐

  1. ora01219数据库未打开

    今天连接数据后,一看提示ora01219数据库未打开,关了服务重开仍然是这样,在度娘找了下才发现问题 应该是我删除了一个数据文件,看下解决办法 错误原因: 直接关闭数据库,然后删除DBF文件.即表空间 ...

  2. MVC下的DAO接口类和SERVICE接口类区别?

    简单理解: DAO数据库访问对象 实现连接数据库 修改.添加等细节 service服务层 面向功能 把一个整个服务 细化 调用DAO其实service其中都是一些方法 去调用DAO 甚至方法名都和DA ...

  3. java面试第九天

    图形界面: 布局管理器: CardLayout:卡片布局,面板重叠放置,只能看到一个,最先添加的会被显示出来,可以进行翻动 两种构造方法: CardLayout() 创建一个间隙大小为 0 的新卡片布 ...

  4. 检测和删除多余无用的css

    本文主要讲解如何检测页面中多余无用的css. 1.chrome浏览器 F12审查元素的Audits 说明:使用Audits,会检测出页面中没有用到的css,需要手动删除多余的css:同时需要说明的是检 ...

  5. 简单说说Ubuntu利用bzr源码安装OpenERP7.0的操作步骤

    1.修改Ubuntu国内更新源,具体方法自己baidu.google. 修改更新源后,更新系统 sudo apt-get update sudo apt-get upgrade 复制代码 2.安装Po ...

  6. eclipse Java compiler level does not match the version of the installed Java project facet.

      eclipse Java compiler level does not match the version of the installed Java project facet. Create ...

  7. 1、redis之安装与配置

    下载安装: redis-server.exe redis服务器的daemon启动程序 redis.conf redis配置文件 redis-cli.exe redis命令行操作工具.当然,也可以用te ...

  8. 一些常见http状态码

    # encoding=utf-8 #python 2.7.10 #xiaodeng #http状态码 #HTTP权威指南 10页 #一些常见状态码: 200 OK,文档正确返回 302 重定向,到其他 ...

  9. 【TP3.2】:日志记录和查看

    1.TP3.2手册日志类链接:http://document.thinkphp.cn/manual_3_2.html#log 2.日志默认路径:/Application/Runtime/Logs 3. ...

  10. iOS中的#import和class区别

    在ios中我们经常会在.h和.m中引入一些类啊等等一般用的是#import来进行声明,你们可能也见到在.h文件进用@class来声明的,那么#import和@class进行声明 到底有什么的区别呢?下 ...