零.资料与前言

0x1 材料:

  1.帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)

0x2 前言

  之前也尝试总结过 js 中的 __proto__ 、 prototype 以及原型链相关的资料(JS 中的原型 -- prototype、__proto__ 以及原型链),不过彼时受限于经验等因素,没有多少条理,同时也存在诸多的的疑点。

  学习嘛,就是一个不断推翻自己的过程,本次总结如下:

一、总览

  以下例子贯穿全文...

function Foo(age) {
this.age = age;
} let f1 = new Foo(16);

  先来张整体图解(原图较大,建议新标签页内观看):

  看着这花花绿绿的线条,头真的很大...不过没关系,分解过来看。

  注意: 图中的 '()' 仅代表这是一个函数对象,并非执行函数运算符。

二、__proto__

  __proto__ 在 ECMA 标准中是 [[Prototype]] ,各家浏览器的实现不一样,在 chrome 中就是 __proto__ ,稍微留意下即可。

  __proto__ 属性,当中存放(指向)着的是一个对象,粗略地讲就是以 “{ key: value }” 这种形式存在的对象(这里主要的为和 js 中的函数对象区分开来)。

  __proto__ 这个属性,理应是 “{k: v}” 对象所独有的,但是因为 js 中万物皆对象,所以 js 函数也是一种对象,所以函数也同样拥有这个属性,也正是因为这样,极容易产生困惑。

  我们从总图中把 __proto__ 单独抽出来:

  如上图所示,一个对象(f1)的 __proto__ 指向的另一个对象的,即指向它们的原型对象(也可以理解为父对象)。

  这个属性的作用是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,如果父对象也不存在这个属性,则继续往父对象的 __proto__ 属性所指向的那个对象(爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端null(原始人。。。),再往上找就相当于在null上取值,会报错。

  通过这样一种链条式的值查找,就是我们常见的原型链,同时,这也是我们模拟继承的常用方法。

三、prototype 属性

  prototype 属性,函数独有,其存放(指向)的同样是一个对象

  从总图中将 prototype 抽出来:

  prototype 中存放的同样是一个对象,这个对象的含义是函数的原型对象,也就是以这个函数作为构造函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象,即 f1.__proto__ === Foo.prototype,这两个属性均指向同一个对象。

  prototype 的作用是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。任何函数在创建的时候,其实会默认同时创建该函数的prototype对象。

四、 constructor 属性(函数)

  constructor 属性,和 __proto__ 一样,理应是对象独有,不过嘛,因为 js 所以 函数也有,但是不常用,故留意下即可。

  constructor 属性(变量),当中存放(指向)的是一个函数

  constructor 中存放的这个函数,就是该对象的构造函数,如对象 f1 以 Foo 为构造函数,那么  f1.constructor == Foo // true 。

  从上图中可以看到,所有的箭头都指向 Function 这个函数,并且 Function 的 constructor 是指向自己,故 constructor 属性的重点就是 Function 这个函数。如: Foo.constructor == Function // true 。

  从第 三 点我们知道,任何函数在创建的时候,其实会默认同时创建该函数的prototype对象。而在创建的这个 prototype 对象的时候,其中的 constructor 会显示指向这个函数,即上图中的  Foo.prototype.constructor == Foo 

五、总结

  1. __proto__ 和 constructor 是对象独有(伪)的;prototype 则是函数独有的;
  2. __proto__ 和 prototype 本身(存储的)是对象,constructor 本身(存储的)是函数;
  3. __proto__ 的常见作用是提供原型链, 以模拟继承特性;
  4. prototype 的常见作用是(自)定义其子代对象的公用属性和方法,并配合原型链提供给所有子代,即  f1.__proto__ == Foo.prototype ;
  5. constructor 的含义是存储(指向)该对象的构造函数;

  以上为本次总结的内容,如有缺陷,还望斧正。

js - __proto__ 、 prototype和constructor的更多相关文章

  1. js中prototype,constructor的理解

    连看4篇前辈的文章,记录一些知识点 Javascript继承机制的设计思想 Javascript 面向对象编程(一):封装 Javascript面向对象编程(二):构造函数的继承 Javascript ...

  2. 彻底搞懂js __proto__ prototype constructor

    在开始之前,必须要知道的是:对象具有__proto__.constructor(函数也是对象固也具有以上)属性,而函数独有prototype 在博客园看到一张图分析到位很彻底,这里共享: 刚开始看这图 ...

  3. js中prototype和constructor的认识

    最初对js中 object.constructor 的认识: 我们都知道,在JS中有一个function的东西.一般人们叫它函数.比如下面的代码 function Person(name)    {  ...

  4. js继承 prototype和constructor

    function a(){                 this.name="aaa";             }             function b(){     ...

  5. Js中Prototype、__proto__、Constructor、Object、Function关系介绍

    一. Prototype.__proto__与Object.Function关系介绍 Function.Object:都是Js自带的函数对象.prototype,每一个函数对象都有一个显式的proto ...

  6. 关于JS call apply 对象、对象实例、prototype、Constructor、__proto__

    关于call与apply的理解容易让人凌乱,这里有个方法可供参考 tiger.call(fox,arg1,arg2...) tiger.apply(fox,[arg1,arg2...]) 理解为 fo ...

  7. JS的prototype和__proto__、constructor

    看了JS的prototype和__proto__这篇文章,才感觉很清晰了,对于原型这块,以前经常把这些属性弄不清楚, 明白了之后保存下整理下: prototype: 是函数的一个属性(每个函数都有一个 ...

  8. 【转】Js中Prototype、__proto__、Constructor、Object、Function关系介绍

    一    Prototype.__proto__与Object.Function关系介绍        Function.Object:Js自带的函数对象.         prototype,每一个 ...

  9. JS中关于构造函数、原型链、prototype、constructor、instanceof、__proto__属性

    在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中引入 ...

  10. javascript中prototype、constructor以及__proto__之间的三角关系

    三者暧昧关系简单整理 在javascript中,prototype.constructor以及__proto__之间有着“著名”的剪不断理还乱的三角关系,楼主就着自己对它们的浅显认识,来粗略地理理以备 ...

随机推荐

  1. elasticsearch-填坑

    1.分页参数 ,start=(page-1)*size 2.高亮字段结果的处理方式 3.float类型参数从map中取出用double接收 4.结果封装需手动封装 package com.search ...

  2. matlab 高级

    绘图 条形图 x = [1:10]; y = [75, 58, 90, 87, 50, 85, 92, 75, 60, 95]; bar(x,y), xlabel('Student'),ylabel( ...

  3. Thinkcmf子栏目获取父级栏目所有子栏目列表

    网站建设时经常需要输出某个栏目的子栏目,对应的在子栏目列表页也需要输出父级栏目的子栏目列表,thinkcmf可以输出所有子栏目,但却无法在子栏目列表页也适用, 因此就需要通过对数据库表查询来完成需求: ...

  4. LA 3882 经典约瑟夫环问题的数学递推解法

    就是经典约瑟夫环问题的裸题 我一开始一直没理解这个递推是怎么来的,后来终于理解了 假设问题是从n个人编号分别为0...n-1,取第k个, 则第k个人编号为k-1的淘汰,剩下的编号为  0,1,2,3. ...

  5. 01 语言基础+高级:1-6 集合_day02【Collection、泛型】

    day02[Collection.泛型] 主要内容 Collection集合 迭代器 增强for 泛型 教学目标 能够说出集合与数组的区别 说出Collection集合的常用功能 能够使用迭代器对集合 ...

  6. 黑马_13 Spring Boot:05.spring boot 整合其他技术

    13 Spring Boot: 01.spring boot 介绍&&02.spring boot 入门 04.spring boot 配置文件 05.spring boot 整合其他 ...

  7. PAT Advanced 1044 Shopping in Mars (25) [⼆分查找]

    题目 Shopping in Mars is quite a diferent experience. The Mars people pay by chained diamonds. Each di ...

  8. python-变量及其数据类型-01

    目录 python-变量及其数据类型-01 1. 第一个python程序 2. 注释 3. 变量 4. 关键字 5. 变量的类型 python-变量及其数据类型-01 1. 第一个python程序 p ...

  9. 题解 P4171 【[JSOI2010]满汉全席】

    什么,tarjan?那是什么? 码量太大,我选择放弃 为什么不用dfs写2-sat呢?他会伤心的说 这题2-sat的过程大佬们已经讲得非常清楚了,我就略微提一下,主要讲dfs的原理 2_sat原理 我 ...

  10. cygwin下命令行下切换目录

    比我们正常切换目录多个挂载的文件夹 cygdrive