普通对象以外的对象

对于普通对象,我们理解了它的 key-value 数据结构 和 原型链相关的知识 基本就可以了,但是如果想用好JS的对象还远远不够。

因为我们日常工作中,接触到的主要 API,几乎都是由这些对象提供的。

根据对象的来源来分类

  • 宿主对象
  • 内置对象
    • 固有对象:
    • 原生对象
    • 普通对象

宿主对象

  JavaScript 宿主环境提供的对象。

  例如浏览器的window、document,Node的global

  window 和 global 里面有一些就是宿主对象,有一些就是内置对象

内置对象

  由 JavaScript 语言提供的对象

  固有对象

    随着 JavaScript 运行时(Runtime)创建而自动创建的对象实例 (程序运行生命周期:编译时、链接时、加载时、运行时)

    ECMA 标准为我们提供了一份固有对象表,里面含有 150+ 个固有对象,但是自己遍历了一下有 900+ 个固有对象

    例如: Math、JSON、Symbol、Promise、Boolean、Array....

  原生对象

    可以由用户通过 Array、RegExp 等内置构造器或者特殊语法创建的对象

  普通对象

    由{}语法、Object 构造器或者 class 关键字定义类创建的对象

函数对象和构造器对象

  在Javascript中,除了原始类型,其他都是对象。其中很特殊的对象是函数和构造器。

  JavaScript 用对象模拟函数的设计代替了一般编程语言中的函数。

    函数对象:具有 [[call]] 私有字段的对象

    构造器对象:具有私有字段 [[construct]] 的对象。

    用 function 关键字来创建的函数,它是必定是同时是函数和构造器。

    同一个函数而言,作为函数和构造器使用时,它们的表现会不太一致。

  [[construct]]的步骤大概可以分成3步:

    1. 以 fn.prototype 为原型创建新对象 

    2. 以新对象为this,调用[[call]] 

    3. 如果[[call]]返回的是对象,那么,返回这个对象,否则返回第一步创建的新对象

      有趣的现象: 

        function Person() {

          return {}
        }

        new Person instanceof Person // false

    按照上面的说法,如果是构造器对象的话,那它也必定是函数对象。

  作为函数和构造器使用时不一致的例子:

    1. new String() 和 String()

    2. Symbol 只能作为一个函数来使用(Symbol 应该是一个箭头函数,箭头函数只能作为函数使用,不能作为构造器)

    3. Image 只能作为构造器使用,作为函数使用时会报错

  对象是由 function 创建的,而 function 本身也是一个对象

    我们知道,在一般情况下(没有人为修改)如果一个对象的__proto__是一个函数的prototype,就说明这个对象是由这个函数构建的。

    追踪到最源头的时候,我们又发现了一个有趣的现象(Function:我构造我自己):

      Function.prototype === Function.__proto__

特殊行为的对象

  Array:length 属性根据最大的下标

  Object.prototype:不允许设置 __proto__ 

  Arguments: 对应的下标属性和对应的变量联动联动

    function aaa(name) {
      arguments[0] = '666';
      console.log(name);

    }

    aaa(233); // 最终打印出来666

这是不那么有规律、不那么优雅的知识,但是正是这些特殊的对象,给我们提供了很多基础能力。

原文地址:https://www.cnblogs.com/amiezhang/p/11397779.html