一、概念

1、Prototype:每一个构造函数都有一个原型对象,这个对象就是Prototype。这个构造函数如何找到他的原型对象呢?每个构造函数都会有一个prototype属性,指向它的原型对象。这就是相当于构造函数的一个属性,注意它不是原型链中的那个关键的链子。

2、constructor:每个原型对象都包含一个指向构造函数的指针,这个指针就是constructor,从而实现了构造函数和其原型之间的双向绑定。a.prototype.constructor指向a

3、_proto _ :所有的对象都含有_proto_标签,a对象有_proto_标签,a.prototype也有_proto_标签。你可以简单的理解为指针。它的作用就是原型链形成的关键,靠它串联起来,它会是指向当前对象的构造函数的原型对象。红宝书中也用[[prototype]]表示,是一个意思

举个栗子:

二、Function.prototype比较特殊



如图中所示,右边一列的原型链跟上面讲的没什么两样。但是左边这三个就神奇了,我们都知道所有的原型链的顶端最后都指向Object.prototype。但是他们的构造函数,像Function、Array甚至Object都指向Function.prototype。其实这也好理解,刚刚也说了嘛,他们都是构造函数,既然是函数,当然会乖乖的归在Function.prototype下了。当然最后仍然归一到了Object.prototype!!

也就是说所有的构造函数的_ _proto_ _如果没有改写的话都是指向Function.prototype。一个函数的constructor都是Function,具体原因看完下面第三部分就明白了。

三、红宝书的例子详解

function SuperType(){
this.property=true;
}
SuperType.prototype.getSuperValue=function(){
return this.property;
};
function SubType(){
this.subproperty=false;
}
//继承了SuperType
SubType.prototype=new SuperType();
SubType.prototype.getSubValue=function(){
return this.subproperty;
};
var instance=new SubType();
alert(instance.getSuperValue());

这个例子是红宝书原型链继承的一个例子,书中也画了图解。作为初学者,可能会犯很多错误,下图就是之前我自以为是的“完善的图”,但其实都是画蛇添足。

下面是错误示例!!!



注意

上图有很多错误,下面我从上到下的顺序一一指正出来。

  • 1、SuperType的_ proto _属性不是null,而是Function.prototype。

  • 2、SubType的_ proto _属性不是null,而是Function.prototype.

  • 3、SuperType.prototype的_ proto _是最指向Object.prototype,这个是因为手抖,箭头下滑了。

  • 4、SubType.prototype没有constructor属性。这是为什么呢?因为在代码运行到

    SubType.prototype=new SuperType();这步之前还是有constructor属性的并且指向SubType。但是这条语句执行完后,SubType的prototype被重写了,执行完SuperType构造函数得到了一些属性和方法。之前自己的属性方法全部没了。所以现在SubType.prototype并没有constructor,它沿着原型链向上查找,查找到SuperType.prototype才找到。

    所以你执行SubType.prototype.constructor的返回值是SuperType,但是SubType.prototype.hasOwnProperty("constructor")返回值是false。

  • 5、instance.prototype是不存在的,因为只有构造函数具有原型对象。instance只是一个实例,是一个Object。

  • 6、instance.constructor也不存在,理由因为只有prototype原型对象具有constructor属性。instance.constructor返回值是SuperType构造函数,那是因为instance没有这个属性,它向上查找一直查找到SuperType.prototype才找到。

正确的图解

原型链、prototype、_proto_那些事的更多相关文章

  1. JavaScript原型链:prototype与__proto__

    title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...

  2. 原型和原型链 prototype和proto的区别

    原型 原型是function对象下的属性,它定义了构造函数的共同祖先,也就是一个父子级的关系,子对象会继承父对象的方法和属性 prototype是函数下的属性,对象想要查看原型使用隐式属性__Prot ...

  3. js 原型链 prototype __proto__

    1.说明 函数(Function)才有prototype属性,对象(除Object)拥有__proto__. 2.prototype与__proto__区别 示例: <!DOCTYPE html ...

  4. js原型链prototype与__proto__以及new表达式

    对象模型的细节 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model

  5. 理解 JavaScript 对象原型、原型链如何工作、如何向 prototype 属性添加新的方法。

    JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板.从原型继承方法和属性.原型对象也可能拥有原型, ...

  6. JavaScript prototype原型链介绍

    javascript 是一种基于原型的编程 (prototype based programming) 的语言, 而与我们通常的基于类编程 (class based programming) 有很大的 ...

  7. javascript中的对象,原型,原型链和面向对象

    一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...

  8. JavaScript系列:再巩固-原型链

    图 1.实例:'对象(实例)'有属性__proto__,指向该对象(实例)的'构造函数的原型对象'. 2.方法:'构造函数'除了有属性__proto__,所有构造函数方法的__proto__指向Fun ...

  9. 关于js中的原型链的理解

    我们知道无论什么时候只要创建了一个函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象,默认情况下所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包 ...

  10. [我的理解]Javascript的原型与原型链

    一.原型与原型链的定义 原型:为其他对象提供共享属性的对象 注:当构造器创建一个对象,为了解决对象的属性引用,该对象会隐式引用构造器的"prototype"属性.程序通过const ...

随机推荐

  1. API模板

    #include <windows.h> #include <windowsx.h> #define DIVISIONS 5 LRESULT CALLBACK WndProc ...

  2. MySQL主从复制的原理和实践操作

    MySQL 主从(MySQL Replication),主要用于 MySQL 的实时备份.高可用HA.读写分离.在配置主从复制之前需要先准备 2 台 MySQL 服务器. 一.MySQL主从原理 1. ...

  3. python数据结构(一)------序列

    数据结构是通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合:在Python中,最基本的数据结构是序列(sequence),序列中的每个元素被分配一个序列号--即元素的位置,也称为索引. p ...

  4. 纪中集训 Day 6

    今天他们回去了,就剩我和DWJ(一位初三大大(后来问云神才知道的ORZ))一起在做题,不得不说他真的是太厉害了,一个升初三大大在各种方面都比我强QAQ 让我突然感觉到自己的高一还是不够努力啊QAQ 连 ...

  5. canvas实例:旋转缩放的方块

    首先在页面中创建一个canvas标签: <body> <canvas id="c1" width="500" height="500 ...

  6. struts2.5框架使用通配符指定方法(常见错误)

    在学习struts框架时经常会使用到通配符调用方法,如下: <package name="shop" namespace="/" extends=&quo ...

  7. ASP.NET Core MVC上传、导入、导出知多少

    前言 本君已成夜猫子,本节我们来讲讲ASP.NET Core MVC中的上传,这两天才研究批量导入功能,本节顺便简单搞搞导入.导出,等博主弄妥当了再来和大家一并分享. .NET Core MVC上传 ...

  8. 每天一个Linux命令(11)--nl命令

    nl命令在Linux系统中用来计算文件中行号.nl可以将输出的文件内容自动的加上行号,其默认的结果与cat -n 有点不太一样,nl可以将行号做比较多的显示设计,包括位数与是否自动不起0等等的功能. ...

  9. 关于adb重启的一些问题

    有时候我们在使用eclipse启动虚拟机进行程序测试的时候会提示,要我们重启adb和eclipse,这个时候,重启adb的方式就是,使用cmd定位到adb所在的文件夹,然后输入指令:adb kill- ...

  10. Spring MVC + Security 4 初体验(Java配置版)

    spring Version = 4.3.6.RELEASE springSecurityVersion = 4.2.1.RELEASE Gradle 3.0 + Eclipse Neno(4.6) ...