JavaScript原型&原型链

原型与原型链是 js 的重点,之前虽然有学习过,但时间一长又忘了;这次整理了网上的一些文章,也将自己的理解记下来


  • 先上图(将这张图理解以后问题应该就不大了)


  • 上代码(以下笔记都根据这段代码进行理解)
function Foo(){};
let f1 = new Foo();

  1. 属性&名词解释

    • 构造函数

      • 用来初始化新创建的对象的函数是构造函数。在例子中,Foo()函数是构造函数
      • 当一个函数创建好以后,并不能知道它是不是构造函数,即使函数名为大写也不能确定。只有当一个函数以 new 关键字来调用的时候,才能说它是一个构造函数
      • 构造函数执行过程
        • 当以 new 关键字调用时,会创建一个新的内存空间,标记为 Foo 的实例。
        • 函数体内部的 this 指向该内存
        • 执行函数体内的代码
        • 默认返回 this
    • 实例对象

      • 通过构造函数的 new 操作创建的对象是实例对象。可以用一个构造函数,构造多个实例对象,f1 是 Foo 的实例对象
    • proto

      • 从图中可以看到__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象)
        • 它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端 null,再往上找就相当于在 null 上取值,会报错(到此结束,null 为原型链的终点)
        • 由以上这种通过__proto__属性来连接对象直到 null 的一条链即为我们所谓的原型链
    • prototype

      • 在 JavaScript 中,每个函数都有一个 prototype 属性(只有函数会有 prototype 属性),这个属性指向函数的原型对象。
        • 任何函数在创建的时候,其实会默认同时创建该函数的 prototype 对象。
        • f1.__proto__===Foo.prototype
        • 它的作用就是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。
    • constructor

      • 每个原型都有一个 constructor 属性,指向该关联的构造函数。
        • 由于实例对象可以继承原型对象的属性,所以实例对象也拥有 constructor 属性,同样指向原型对象对应的构造函数
          • f1.constructor===Foo&&f1.constructor===Foo.prototype.constructot
        • Function 这个对象比较特殊,它的构造函数就是它自己,所有函数和对象最终都是由 Function 构造函数得来,所以 constructor 属性的终点就是 Function 这个函数
    • Function

      • 函数也是对象,只不过是具有特殊功能的对象而已。任何函数都可以看做是通过 Function()构造函数的 new 操作实例化的结果
      • 所有的函数都可以看成是构造函数 Function()的 new 操作的实例化对象。那么,Function 可以看成是调用其自身的 new 操作的实例化的结果
      • 如果 Function.prototype 作为实例对象的话,其原型对象是什么呢?和前面一样,所有的对象都可以看成是 Object()构造函数的 new 操作的实例化结果。所以,Function.prototype 的原型对象是 Object.prototype,其原型函数是 Object()
  2. 总结

    • 原型

      • 我的理解
        • Foo.prototype 是Foo的原型对象,是 f1 的原型;
    • 原型链

      • 简单的回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。这就是所谓的原型链的基本概念。——摘自《javascript 高级程序设计》
      • 通俗的理解在__proto__中有解释(好像不支持锚点定位)

最后附上参考的几篇文章

  • 帮你彻底搞懂 JS 中的 prototype、__proto**与 constructor(图解)
  • 一张图理解 prototype、proto 和 constructor 的三角关系
  • javascript——原型与原型链

你可能感兴趣的:(JavaScript原型&原型链)