• 原型与原型链一知半解


    前言

    看过不少深入了解原型原型链系列,大体是明白不少,还是不够透彻!以下仅为个人总结和理解。

    初见各名词

    首先得了解这几个词:
    函数,构造函数,函数原型(实例原型),实例,实例对象,对象原型,原型,prototype,proto,constructor

    先看下面这个例子:

    function Person() {
    
    }
    function Foo() {
    
    }
    const foo = new Foo();
    const person = new Person();
    
    

    函数,构造函数:在上面的例子中构造函数就是Person

    函数原型(实例原型):后面会结合式子阐述。(我的理解是最初始的函数,他的属性所有函数使用)

    实例与实例对象:在上面的例子中,有构造函数Person、Foo,我们用new操作符实例化了foo实例对象、person实例对象

    原型对象与原型:后面会结合式子阐述。

    原型

    任何一个构造函数都会有prototype属性。打印构造函数Foo.prototype,Person.prototype你会发现

    console.log(Foo.prototype,Person.prototype);
    //{ constructor: f Foo(), __proto__: Object } { constructor: f Person(), __proto__: Object }
    

    Foo.prototype,Person.prototype它们都指向各自函数的原型对象

    a) 任何一个构造函数函数(Person,Foo),都拥有一个prototype属性,它指向这个函数的原型对象

    从打印出来的式子

    { 
      constructor: f Foo(),
      __proto__: Object 
    } 
    { 
    constructor: 
      constructor: f Person(),
      __proto__: Object 
    }
    

    不难看出 Person.prototype和Foo.prototype都有constructor和__proto__属性。

    而且Person.prototype.constructor和Foo.prototype.constructor都指向的是各自的构造函数本身。

    可以通过式子大胆验证下:

    console.log(Person.prototype.constructor === Person) // true
    console.log(Foo.prototype.constructor === Foo) // true
    

    b) 构造函数的prototype的constructor都是指向的构造函数的本身

    那么Person.prototype.__proto__和Foo.prototype.__proto__指向什么呢?

    console.log(Person.prototype.__proto__ === Object.prototype) // true
    console.log(Foo.prototype.__proto__ === Object.prototype) // true
    

    上式中的Person.prototype.__proto__和Foo.prototype.__proto__都指向Object.prototype

    c) Person.prototype的原型指向Object.prototype

    也就是说每个函数的原型都是Object的实例,那么Object.prototype的原型,new出来的foo,person的原型呢?

    console.log(foo.__proto__);//{ constructor: f Foo(), __proto__: Object } 
    console.log(person.__proto__);//{ constructor: f Person(), __proto__: Object }
    console.log(Object.prototype.__proto__);//null
    

    不难看出

    console.log(foo.__proto__===Foo.prototype);//true
    console.log(person.__proto__===Person.prototype);//true
    console.log(Object.prototype.__proto__===null);//true
    

    d) foo,person的__proto(实例的原型) === Person.prototype;因此把Person.prototype叫做实例原型。

    e) Person.prototype.proto(实例原型的原型) === Object.prototype;因此实例原型的原型指向的是Object.prototype。

    f) Object.prototype.proto(Object.prototype的原型) === null;因此Object.prototype.proto 的值为null,也就是Object.prototype没有原型。

    再上面的 b 项中式子拿下来(b.构造函数的prototype的constructor都是指向的构造函数的本身)

    console.log(Person.prototype.constructor === Person) // true
    console.log(Foo.prototype.constructor === Foo) // true
    

    那么Object.prototype.constructor是不是也是Object本身呢?

    console.log(Object.prototype.constructor===Object)//true
    

    g) Object.prototype.constructor === Object

    由此讶羽大佬的关系图也就清晰了
    原型链

    原型链

    由上面的分析,可以看出原型链实际上就是运行const foo = new Foo()语句(创建实例函数时),产生了一个链条反应,这个最顶端也就是原型链最顶端是Object.prototype.__proto__为null。

    总结:从一个实例对象往上查找构造这个实例的相关联对象(原型对象),这个关联的对象(原型对象)通过__prototo__属性再往上找创造他的原型对象,以此类推,一直往上找,直到Object.prototype的原型对象为null结束的过程。

    原型链是通过prototype的原型和__proto__的属性来完成原型链的查找。

    原型与原型链一知半解

  • 相关阅读:
    yocto/bitbake 学习资源
    QEMU/KVM学习资源
    ubuntu 中创建和删除用户
    git 重命名本地和远程分支
    Ubuntu 上搭建 FTP 服务器
    gdb 常见用法
    git log 显示与特定文件相关的 commit 信息
    基于 qemu system mode 运行 arm 程序
    基于 qemu user mode 运行 aarch64 程序
    checking in(airport)
  • 原文地址:https://www.cnblogs.com/yihan123/p/14213420.html
Copyright © 2020-2023  润新知