zoukankan      html  css  js  c++  java
  • 原型链的树形结构

      总所周知,js有七种数据类型,其中一种引用类型Object,其他六种基本类型:Number、String、null、undefined、symbol、Boolean。

    在讨论原型的时候,我们讨论的还是这个引用类型Object。

      我们先看一下这段代码

    var a = 20;
    var b = 'abc';
    var c = true;
    var d = { m: 20 }

      通过这段代码我们可以看一看JS的栈内存和堆内存

    JS栈内存与堆内存

      对于引用类型的变量d,我们可以在栈中记录的是其堆中的引用地址。我们可以看到 d 的属性以及值存储在堆中,我们可以通过 d.m 获取20这个值,但我们调用 d.toSting() 时我们可以发现,这个方法是存在的。

    var d = { m: 20 }
    console.log(d.toString())  // '[object Object]'

      为什么有toString 属性

      根据执行结果可以知道toSting是一个函数,也就是属于对象,属于引用类型。

      可以确定,toString 属于引用类型,而对于我们生成的引用变量d来说,它有一种特殊的方式,通过这一方式可以访问toString。同样的这一方式还可以访问 valueOf、isPrototypeOf等方法。

      而每个生成的一个新的对象,我们知道,它们都具有这么一个方式,可以以这个方式访问我们未曾定义的方法集合。

      在我们先将这个方式称之为 ‘共’  ,如图所示。

      我们定义一个对象obj,在chrome浏览器里

      var obj = {
        name:'he',
      }
      console.dir(obj)

      我们可以看到打印出来的结果

    1. obj 本身有一个属性 name(这是我们给它加的)
    2. obj 还有一个属性叫做 __proto__(它是一个对象)
    3. obj.__proto__ 有很多属性,包括 valueOf、toString、constructor、hasOwnProperty 等

      也就是说这个的属性名的真正名字就是 __proto__ 也就是我们平时说的原型。
      而obj.__proto__ 指向的集合,也就称之为 Object.prototype

      现在回到我们的问题:obj 为什么会拥有 valueOf / toString / constructor等属性?

      答案:这跟 __proto__ 有关。

      对于 obj 来说,本身不具有toString / valueOf 方法,通过 __prototype__ 以后可以 以 obj.toString 进行访问

      当我们读取obj.toString 时,JS引擎是这样的

    1. 查询 obj 本身是否有toString属性,没有就到下一步
    2. 查询obj.__proto__ 上是否有toString属性,没有就到下一步
    3. 查询obj.__proto__.__proto__ (此时为null)上是否有toString属性,没有就继续查找

         对于obj来说,在obj.__proto__ 找到toSting,所以调用 obj.__proto.toString 方法
      而在这一过程中,也就是 [读取属性] 的过程中,就像摸着链子一步一步寻找目的地一样。

      这条链子,我们就称之为原型链

      

      当然,这只是对 new Object() 生成的对象,当我们把整个原型链可以放置到所有的数据结构时, 每个不同类型的对象也同样会拥有他们不同的集合。

      所以,数组有一个 Array.prototype、函数有一个Function.prototype、Number类型对象有一个Number.prototype 。。。

      JS一切皆对象,其实Array.prototype 、Function.prototype ... 都属于 Object类型。

    var arr = [1,2,3]
    console.log(arr.toString())   // 1,2,3

      我们可以画图

      注:原型链的部分树形结构

    • [p] 表示的是 __proto__
    •  console.log方法,Array.prototype 打印出来为数组,Function.prototype无法打印结果
    • 建议使用console.dir()打印,以便查看结果
    • 。。。 表示包括String、Symbol、Date、Number、Boolean、Error....

      总结:

    1. JS中为了方便区分,生成了许多如Array、Function、String...不同的数据类型
    2. 每个数据类型的通用属性集合被放置在一个对象中,用户定义的变量根据其数据类型可以获取不同的方法,同时其顶端都属于Object.prototype

      

      延伸:obj 的由 Object所构造,但Array,Function又是由谁构造出来的呢。也就是说构造函数是什么情况呢?

      参考资料:JavaScript万物诞生记

      这篇文章通过比较诙谐的方式,以现有的证据来说明了JS不同数据类型是怎么出现的

  • 相关阅读:
    2021/9/20 开始排序算法
    快速排序(自己版本)
    2021/9/17(栈实现+中后缀表达式求值)
    2021/9/18+19(中缀转后缀 + 递归 迷宫 + 八皇后)
    20212021/9/13 稀疏数组
    2021/9/12 线性表之ArrayList
    开发环境重整
    Nginx入门
    《财富的帝国》读书笔记
    Linux入门
  • 原文地址:https://www.cnblogs.com/h246802/p/9794264.html
Copyright © 2011-2022 走看看