-
JavaScript 中的对象分类
A. 宿主对象 由 JavaScript 宿主环境提供的对象,它们的行为完全由宿主环境决定
浏览器对象B. 内置对象 由 JavaScript 语言提供的对象
a. 固有对象 由标准规定,随着 JavaScript 运行时创建而自动创建的对象实例 三个值: Infinity、NaN、undefined 九个函数: 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、Typed Array、Float32Array、Float64Array、Int8Array、Int16Array、Int32Array、UInt8Array、UInt16Array、UInt32Array、UInt8ClampedArray。 四个用于当作命名空间的对象: Atomics JSON Math Reflect 找出所有固有对象 : 使用广度优先搜索 查找这些对象所有的属性和 Getter/Setter 就可以获得 JS 所有固有对象 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); } } b. 原生对象 可以由用户通过 Array、RegExp 等内置构造器或者特殊语法创建的对象 可以通过new 运算创建新的对象 称为原生对象 typeof new Date // object typeof Date() // string 他们实现 [[call]] [[construct]] 实现的结果不总是一致的 new 的执行过程: A. 以构造器的prototype属性为原型创建新对象 B. 将this和调用参数传给构造器执行 C. 如果构造器返回对象 则返回 否则返回第一步创建 [[construct]] 执行过程: 以 Object.prototype 为原型创建一个新对象; 以新对象为 this,执行函数的[[call]]; 如果[[call]]的返回值是对象,那么,返回这个对象,否则返回第一步创建的新对象。 function cls(){ this.a = 100; return { getValue:() => this.a } } var o = new cls; o.getValue(); //100 //a在外面永远无法访问到 特殊行为对象 Array:Array 的 length 属性根据最大的下标自动发生变化。 Object.prototype:作为所有正常对象的默认原型,不能再给它设置原型了。 String:为了支持下标运算,String 的正整数属性访问会去字符串里查找。 Arguments:arguments 的非负整数型下标属性跟对应的变量联动。 模块的 namespace 对象:特殊的地方非常多,跟一般对象完全不一样,尽量只用于 import 吧。 类型数组和数组缓冲区:跟内存块相关联,下标运算比较特殊。 bind 后的 function:跟原来的函数相关联。 * JS中的构造器: 基本类型 Boolean String Number Symbol Object 基础功能和数据结构 Array Date RegExp Promise Proxy Map WeakMap Set WeakSet Function 错误类型 Error EvalError RangeError ReferenceRrror SyntaxError TypeError URIError 二进制操作 ArrayBuffer SharedArrayBuffer DataView 带类型的数组 Float32Array Float64Array int8Array int16Array int32Array UInt8Array UInt16Array UInt32Array UInt8ClampedArray 这些构造器创建的对象多数使用了私有字段: Error: [[ErrorData]] Boolean: [[BooleanData]] Number: [[NumberData]] Date: [[DateValue]] RegExp: [[RegExpMatcher]] Symbol: [[SymbolData]] Map: [[MapData]] c. 普通对象 由{}语法、Object 构造器或者 class 关键字定义类创建的对象,它能够被原型继承 函数对象 具有[[call]]私有字段 [[call]]私有字段必须是一个引擎中定义的函数 需要接受this值和调用参数,并且会产生域的切换 构造器对象 具有[[construct]]私有字段