重学前端学习笔记(九)--JavaScript中的对象分类

笔记说明

重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏, 天天10分钟,重构你的前端知识体系,笔者主要整理学习过程的一些要点笔记以及感悟,完整的能够加入winter的专栏学习【原文有winter的语音】,若有侵权请联系我,邮箱:kaimo313@foxmail.com。

1、javaScript对象分类介绍

1.0、宿主对象(host Objects)

由 JavaScript 宿主环境提供的对象,它们的行为彻底由宿主环境决定。

1.一、内置对象(Built-in Objects)

由 JavaScript 语言提供的对象。

1.1.0、固有对象(Intrinsic Objects )

由标准规定,随着 JavaScript 运行时建立而自动建立的对象实例。

1.1.一、原生对象(Native Objects)

能够由用户经过 Array、RegExp 等内置构造器或者特殊语法建立的对象。

1.1.二、普通对象(Ordinary Objects)

{} 语法、 Object 构造器或者 class 关键字定义类建立的对象,它可以被原型继承。

下面winter主要介绍了普通对象以外的对象原型(恰好都是我不太懂的,mark一下)html

2、宿主对象

2.0、window对象

  • 全局对象 window 上的属性,一部分来自 JavaScript 语言,一部分来自浏览器环境
  • 宿主也会提供一些构造器,好比使用 new Image来建立 img 元素(winter下次会讲浏览器的API,到时再详细的mark一下)

3、内置对象·固有对象

3.0、简单介绍

  • 固有对象在任何 JS 代码执行前就已经被建立出来,相似基础库的角色
  • ECMA 标准为咱们提供了一份固有对象表,里面含有 150+ 个固有对象(连接打开比较慢,稍等一下就好)

3.一、小实验:获取所有 JavaScript 固有对象

3.1.0、三个值

Infinity、NaN、undefined

3.1.一、九个函数

eval、isFinite、isNaN、parseFloat、parseInt、decodeURI decodeURIComponent、encodeURI、encodeURIComponent

3.1.二、一些构造器

Array、Date、RegExp、Promise、Proxy、Map、WeakMap、Set、WeapSet、Function、Boolean、String、Number、Symbol、Object、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError URIError、ArrayBuffer、SharedArrayBuffer、DataView、Typed Array、Float32Array、Float64Array、Int8Array、Int16Array、Int32Array、UInt8Array、UInt16Array、UInt32Array、UInt8ClampedArray

3.1.三、四个用于看成命名空间的对象

Atomics、JSON、Math、Reflect

3.1.四、处理方法

一、winter的作法:使用广度优先搜索,查找这些对象全部的属性和 Getter/Setter,就能够得到 JavaScript 中全部的固有对象。前端

二、下面代码能够研究一下看看,new Set()不懂的能够看看MDN关于set的介绍,(我如今尚未看明白,我去不一样网页打开运行输出set不同,感受有点懵逼_(:3」∠)_,理解的大佬能够留言告诉我,不胜感激)java

var set = new Set();
var objects = [
    eval,
    isFinite,
    isNaN,
    parseFloat,
    parseInt,
    decodeURI,
    decodeURIComponent,
    encodeURI,
    encodeURIComponent,
    Array,
    Date,
    RegExp,
    Promise,
    Proxy,
    Map,
    WeakMap,
    Set,
    WeakSet,
    Function,
    Boolean,
    String,
    Number,
    Symbol,
    Object,
    Error,
    EvalError,
    RangeError,
    ReferenceError,
    SyntaxError,
    TypeError,
    URIError,
    ArrayBuffer,
    SharedArrayBuffer,
    DataView,
    Float32Array,
    Float64Array,
    Int8Array,
    Int16Array,
    Int32Array,
    Uint8Array,
    Uint16Array,
    Uint32Array,
    Uint8ClampedArray,
    Atomics,
    JSON,
    Math,
    Reflect];
objects.forEach(o => set.add(o));

for(var i = 0; i < objects.length; i++) {
    var o = objects[i]
    for(var p of Object.getOwnPropertyNames(o)) {
        var d = Object.getOwnPropertyDescriptor(o, p)
        if( (d.value !== null && typeof d.value === "object") || (typeof d.value === "function"))
            if(!set.has(d.value))
                set.add(d.value), objects.push(d.value);
        if( d.get )
            if(!set.has(d.get))
                set.add(d.get), objects.push(d.get);
        if( d.set )
            if(!set.has(d.set))
                set.add(d.set), objects.push(d.set);
    }
}

4、内置对象·原生对象

4.0、分类

winter按照不一样应用场景,将原生对象分红了如下几个种类

原生对象种类

4.一、注意的几个点

  • 能够用 new 运算建立新的对象
  • 几乎全部这些构造器的能力都是没法用纯 JavaScript 代码实现
  • 也没法用 class/extend 语法来继承
  • 建立的对象多数使用了私有字段,好比:Error: [[ErrorData]]...这些字段使得原型继承方法没法正常工做
  • 全部这些原生对象都是为了特定能力或者性能,而设计出来的特权对象

5、用对象来模拟函数与构造器:函数对象与构造器对象

5.0、函数对象的定义

具备 [[call]] 私有字段的对象

[[call]] 私有字段必须是一个引擎中定义的函数,须要接受 this 值和调用参数,而且会产生域的切换数组

5.一、构造器对象的定义

具备 [[construct]] 私有字段的对象

5.1.0、[[construct]] 的大体执行过程

一、以 Object.protoype 为原型建立一个新对象
二、以新对象为 this,执行函数的 [[call]]
三、若是 [[call]] 的返回值是对象,那么,不然返回第一步建立的新对象浏览器

5.二、例子

一、内置对象 Date 在做为构造器调用时产生新的对象,做为函数时,则产生字符串,见如下代码:函数

console.log(new Date);
console.log(Date())

二、浏览器宿主环境中,提供的 Image 构造器,则根本不容许被做为函数调用。性能

console.log(new Image);
console.log(Image()); // 抛出错误 Uncaught TypeError: Failed to construct 'Image': Please use the 'new' operator, this DOM object constructor cannot be called as a function.'Image'

三、基本类型(String、Number、Boolean),它们的构造器被看成函数调用,则产生类型转换的效果学习

四、在 ES6 以后 => 语法建立的函数仅仅是函数,它们没法被看成构造器使用,见如下代码:ui

new (a => 0) // 报错:Uncaught TypeError: (intermediate value) is not a constructor

五、使用 function 语法或者 Function 构造器建立的对象来讲,[[call]][[construct]] 行为老是类似的,它们执行同一段代码。this

function f(){
    return 1;
}
var v = f(); // 把 f 做为函数调用
var o = new f(); // 把 f 做为构造器调用

六、若是构造器返回了一个新的对象,那么 new 建立的新对象就变成了一个构造函数以外彻底没法访问的对象,这必定程度上能够实现私有

function cls(){
    this.a = 100;
    return {
        getValue: () => this.a
    }
}
var o = new cls;
o.getValue(); //100
//a 在外面永远没法访问到

6、特殊行为的对象

6.0、行为不大同样的对象

winter总结了常见的下标运算(就是使用中括号或者点来作属性访问)或者设置原型跟普通对象不一样的对象,以下:
  • ArrayArraylength 属性根据最大的下标自动发生变化。
  • Object.prototype:做为全部正常对象的默认原型,不能再给它设置原型了。
  • String:为了支持下标运算,String 的正整数属性访问会去字符串里查找。
  • Argumentsarguments 的非负整数型下标属性跟对应的变量联动。
  • 模块的 namespace 对象:特殊的地方很是多,跟通常对象彻底不同,尽可能只用于 import
  • 类型数组和数组缓冲区:跟内存块相关联,下标运算比较特殊
  • bind 后的 function:跟原来的函数相关联

我的总结

看完这篇,有点崩溃,如今已经凌晨2点48了,还没搞懂,感受以前学的过于皮毛,这些东西看起来一脸懵逼,哈哈哈...,有时间在好好增强一下这块的知识

相关文章
相关标签/搜索