图解JavaScript原型和原型链

Posted chenyuna

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图解JavaScript原型和原型链相关的知识,希望对你有一定的参考价值。

基础了解

javascript对象可以分为两类:

  1. 普通对象 ,除了函数对象之外的对象都是,包括new函数对象()产生的实例,普通对象没有prototype,也就没有继承和原型链一说。

  2. 函数对象 ,包括两种:

  • 由function创造出来的函数:

        function f1() {
    
        } // 匿名函数
    
        var f2 = function() {
    
        }
    
        var f3 = new Function(‘x‘,‘console.log(x)‘);
    
        // 以上都是函数对象
  • 系统内置的函数对象:

Function,Object,Array,String,Number

进入正题

技术分享图片

上图解释了__proto__、原型对象prototype、构造函数constructor的复杂关系,下面有解释。

解释各个对象的含义

  • function Foo() 即 Foo类

function Foo() {

    this.name = ‘xxx‘;

    ...

} // 构造函数

Foo.prototype.sayName = function() {

    console.log(this.name);

} // 原型对象
  • function Object() 即 js内置对象Object,在javascript中所有的对象都继承自Object。这里用function xxx()表示是因为构造Object对象的源码就是如此,即Object也是类似函数的构造方式。

  • function Function() 即 js内置对象Function。

  • f1,f2 表示 Foo的实例对象

  • o1,o2 表示 Object的实例对象

  • xxx.prototype 表示xxx的原型对象

原型和原型链

原型

1)prototype

即原型对象,只有函数对象有prototype属性,它的主要作用就是继承,将其中定义的属性和方法传递给‘后代’(比如实例化)

2)__proto__

每个对象都有__proto__属性,它的主要作用是储存继承得来的方法和属性。

3)如何继承

以f1为例,继承的过程可以表示为f1.__proto__ = Foo.prototype,即对象.__proto__ = 构造器.prototype,上面的图形可以完全参照这个公式来理解。

原型链

1) f1的原型链。

  1. f1为普通对象,它的构造器为Foo,以Foo为原型,原型链第一链为f1.__proto__ == Foo.prototype

  2. Foo.prototype(注意这边不是Foo)为json对象,即普通对象,构造器为Object,以Object为原型,得出原型链第二链Foo.prototype.__proto__ == Object.prototype;

  3. Object.prototype以Null为原型,原型链第三链为Object.prototype.__proto__ == null

f1的原型链可以用图形表示:

技术分享图片

可以在浏览器console打印验证:

技术分享图片

2) Foo的原型链

  1. Foo为函数对象,它的构造器为Function,以Function为原型,原型链第一链为Foo.__proto__ == Function.prototype;

  2. Function.prototype为json对象,即普通对象,构造器为Object,以Object为原型,原型链第二链为Function.prototype.__proto__ == Object.prototype;

  3. 最后Object.prototype以Null为原型,原型链第三链为Object.prototype.__proto__ == null;

Foo的原型链可以用图形表示为:

技术分享图片

可以在浏览器console打印验证:

技术分享图片

3)小结

列出两种原型链的目的是:

当js引擎执行对象的属性或方法时,先查找对象本身是否存在该方法,如果不存在则会在原型链上查找。因而f1拥有Foo、Object的原型方法,Foo拥有Function、Object的原型方法。注意,虽然f1原型链其中有一链是涉及到函数对象Foo,但f1并不拥有Function的原型方法,因为原型链并没有延伸到Function。

技术分享图片

上图中bind是Function的原型方法,f1并没有拥有。

总结

如何找出一个对象的原型链,只需要两步

  1. 判断对象是普通对象还是函数对象,得出对象的构造器

  2. 对象.proto = 构造器.prototype

关于最上面的图形,只剩Object和Function的特殊关系和构造函数constructor没有讲到,如果有讲不清和讲错了的地方,请帮我指出来,我也跟大家一起在学习中,请轻喷(●ˇ?ˇ●)

以上是关于图解JavaScript原型和原型链的主要内容,如果未能解决你的问题,请参考以下文章

web前端:理解js原型链

[js高手之路]一步步图解javascript的原型(prototype)对象,原型链

[js高手之路]一步步图解javascript的原型(prototype)对象,原型链

javascript原型,原型链 有啥特点

5.JavaScript原型链和继承详解

彻底理解js的原型链