系统对象

yuhuo2021-06-13JavaScriptJavaScript对象

提示

本文需与 《基础 / 对象详解》 一文相结合阅读

PropertyDescriptor 对象

1. 获取对象

// 查看单个自有属性描述对象
var descriptor = Object.getOwnPropertyDescriptor(obj, "key");
// 查看所有自有属性描述对象
var descriptor = Object.getOwnPropertyDescriptors(obj);

2. 对象属性

对象属性类型描述
valueany属性值(数据属性)
writableboolean可写性(数据属性)
getFunction取值方法(存取器属性)
setFunction存值方法(存取器属性)
enumerableboolean可枚举性
configurableboolean可配置性

注意

通过 var 或 function 声明的全局变量,作为 window 的属性都是不可配置的。

当属性为不可配置时:

  • 不能编辑可配置性和可枚举性,可写性只能由 true 设为 false
  • 数据属性和存取器属性不能相互转换
  • 存取器属性不能更改 set 和 get 方法
  • 属性不能被删除

Object 类

1. 创建对象

var obj = new Object();
// writable,enumerable,configurable 默认为 true
var obj = {
    a: 1,
    b,   // 简写,等同 b: b
	c() { },  // 简写,等同 c: function() {}
	[d + "key"]: "value",  // 属性名表达式
    [Symbol()]: "symbol", // symbol属性名
    get e() { // 存取器属性
        return Math.random();
    },
    set e(value) {
        this.a = value;
    }
};
// writable,enumerable,configurable 默认为 false
var obj = Object.create({proto: "原型对象"}, {
	a: {
        value: 1,
        writable: true, 
        enumerable: true,
        configurable: true
    },
    b: {
        get: function(){
            return Math.random();
        },
        set: function(value){
            this.a = value;
        },
        enumerable: true,
        configurable: true
    }
});

2. 静态方法

静态方法描述
属性create(proto: Object, properties?: PropertyDescriptorMap): 根据原型和属性描述对象集合创建新对象并返回
defineProperty(o: T, name: string | symbol, property: PropertyDescriptor): T目标对象定义或修改单个属性,返回目标对象
defineProperties(o: T, properties: PropertyDescriptorMap): T目标对象定义或修改多个属性,返回目标对象
getOwnPropertyDescriptor(o: Object, name: string | symbol): PropertyDescriptor返回目标对象指定自有属性的描述对象
getOwnPropertyDescriptors(o: Object): PropertyDescriptorMap返回目标对象所有自有属性的描述对象集合
============================
遍历keys(o: Object): string[]返回对象自有的可枚举字符串属性名的数组
values(o: Object): any[]返回对象自有的可枚举字符串属性名的值的数组
getOwnPropertyNames(o: Object): string[]返回对象所有自有字符串属性名称的数组
getOwnPropertySymbols(o: Object): symbol[]返回对象所有自有Symbol属性名称的数组
============================
扩展isExtensible(o: Object): boolean返回对象是否可扩展
preventExtensions(o: T): T设置对象为不可扩展,返回原对象
isSealed(o: Object): boolean返回对象是否封闭
seal(o: T): T设置对象为封闭,返回原对象
isFrozen(o: Object): boolean返回对象是否冻结
freeze(o: T): T设置对象为冻结,返回原对象
============================
原型getPrototypeOf(o: Object): Object返回对象的原型
setPrototypeOf(o: Object, proto: Object): Object设置对象原型
============================
工具assign(target: object, ...source: object[]): object将源对象的自身可枚举属性
合并到目标对象中,返回目标对象
entries(o: object | string): [string, any][]分割对象属性或字符串
返回 [属性名, 属性值] 或 [序号, 字符] 的数组
is(value1: any, value2: any): boolean比较两个值是否严格相等,类似 ===
不同之处:
Object.is(+0, -0) → false
Object.is(NaN, NaN) → true

3. 原型属性

原型属性类型描述
constructorFunction当前对象的构造函数
__proto__Object当前对象的原型对象

4. 原型方法

原型方法描述
valueOf(): any返回对象的值,默认当前对象
toString(): string返回对象的字符串,默认"[object Object]"
toLocaleString(): string返回对象的本地字符串,默认 "[object Object]"
hasOwnProperty(name: string | symbol): boolean返回自有属性是否存在
propertyIsEnumerable(key | symbol): boolean返回自有属性是否存在且可枚举
isPrototypeOf(o: Object): boolean返回当前对象是否为目标对象的原型

5. 属性扩展性

属性扩展性
可扩展
不可扩展×
封闭 = 不可扩展 + 属性不可配置××
冻结 = 封闭 + 属性不可写×××

注意

  • 空对象(无法删属性)+ 不可拓展 = 封闭
  • 冻结对象的存取器属性 setter 方法依然有效

6. 属性操作示例

定义属性

// 定义单个属性值
obj.a = 2;
obj["a"] = obj.b;

// 定义单个属性描述对象
Object.defineProperty(obj, "b", {
	value: 2, 
    writable: true, 
    enumerable: true,
    configurable: true
});
// 定义多个属性描述对象
Object.defineProperties(obj, {
   a: {
        value: 1,
        writable: true, 
        enumerable: true,
        configurable: true
    },
    b: {
        get: function(){
            return Math.random();
        },
        set: function(value){
            this.a = value;
        },
        enumerable: true,
        configurable: true
    }
});

获取属性

// 查看自有属性 + 继承属性的值
var value = obj.key;
var value = obj["key"];

// 查看单个自有属性描述对象
var descriptor = Object.getOwnPropertyDescriptor(obj, "key");
// 查看所有自有属性描述对象
var descriptor = Object.getOwnPropertyDescriptors(obj);

删除属性

delete obj.a;
// 非严格模式,删除 window 对象的可配置属性,可省略 window/this
delete Date;

注意

  • 删除只是断开联系,并没有销毁属性值
  • 删除成功或没有副作用(如不存在的属性,非属性表达式),返回 true
  • 不可配置的属性会删除失败,返回 false

检测属性

// 检测自有属性 + 继承属性是否存在
"key" in obj
// 检测自有属性是否存在
obj.hasOwnProperty("key")
// 检测自有属性是否存在且可枚举
obj.propertyIsEnumerable("key")

枚举属性

// 遍历对象自有 + 继承的可枚举字符串属性
for(key in obj) { }

// 获取对象自有的可枚举字符串属性名的数组
var keys = Object.keys(obj);

// 获取对象自有的可枚举字符串属性名的值的数组
var values = Object.values(obj);

// 获取对象所有自有字符串属性名的数组
var keys = Object.getOwnPropertyNames(obj)

// 获取对象所有自有Symbol属性名的数组
var symbols = Object.getOwnPropertySymbols(obj)
可枚举不可枚举
原型属性(String)for...in
原型属性(symbol)
自有属性(String)for...in
Object.keys
Object.values
Object.getOwnPropertyNames

Object.getOwnPropertyNames
自有属性(symbol)Object.getOwnPropertySymbolsObject.getOwnPropertySymbols

Function 类

1. 创建对象

// function 声明
function sum(a, b) { 
    return a + b; 
}
// 匿名函数,参数携带默认值
var sum = function(a = 10, b) { 
    return a + b; 
}
// 箭头函数
var sum = (a, b) => { 
    return a + b; 
}; 
// 单参数可省略参数括号
var sum = a => {
    return a + a;
}; 
// 方法体只有一行 return 时,可省略方法体大括号
var sum = (a, b) => a + b;

// 省略代码块又要返回对象时,需要加括号区分
var sum = a => ({res: a});

// 最后一个参数当方法体
// 一直为全局作用域,即方法体中的变量 c 来自全局作用域 
var sum = new Function("a", "b", "return a + b + c;");

2. 原型属性

对象属性类型描述
namestring返回方法名
lengthnumber返回形参个数
argumentsArguments返回实参对象 [param1, param2..., callee: f],callee 代表方法对象本身(只有在方法体中有值)
同时方法体内自带 arguments 变量可以直接用
callerFunction返回执行方法的作用域对应的函数对象,如在全局作用域运行则返回 null(只有在方法体中有值)

3. 原型方法

原型方法描述
apply(thisArg: any, argArray?: any[]): any指定方法的 this 对象运行方法
call(thisArg: any, ...argArray?: any[]): any指定方法的 this 对象运行方法
bind(thisArg: any, ...argArray?: any[]): any指定方法的 this 对象返回的新方法,运行该新方法来运行原方法

arguments 对象

1. 获取对象

function run(a, b) {
	// 方法体内默认生成的arguments局部变量
    arguments;
    // 当前方法对象的arguments属性
    run.arguments;
}

2. 对象属性

对象属性类型描述
lengthnumber返回实参个数
calleeFunction返回当前方法对象
[index]any返回序号对应的实参

3. 对象方法

对象属性描述
[Symbol.iterator](): IterableIterator返回实参的迭代器对象

Error 类

1. 创建对象

var error = new Error("错误信息");

2. 原型属性

原型属性描述
name错误名称,返回类名
message错误信息

3. 子类

  • SyntaxError:语法错误(在 JS 解析阶段就会抛出,还未到执行阶段)
    • {k:};
    • const a;
    • let b = 1, b = 2;
  • ReferenceError:引用错误
    • notdefined();
  • RangeError:范围错误
    • [].length = -1;
  • TypeError:类型错误
    • new 1;
    • const a = 1;a = 2;
  • URIError:URI 错误
    • decodeURI("%");
  • EvalError:eval 函数执行错误,ES5 开始不会再出现

4. 抛出与捕获

// 自定义错误类
class MyError extends Error {
    name = "自定义错误名称";
};

try {
    // 抛出系统自带错误
    throw new TypeError("错误信息");
    // 抛出自定义错误
    throw new MyError("错误信息");
    // 抛出任何类型的数据
    throw "错误"; 
    
} catch(error) {
    // 捕获错误,error 等于抛出的对象
} finally {
    // 错误与否都最终执行
}

IterableIterator 接口

1. 创建对象

// 来自数组
var array = [1, 2, 3];
var iterator = array[Symbol.iterator]();

// 来自类型化数组
var array = new Int8Array([1, 2, 3]);
var iterator = array[Symbol.iterator]();

// 来自字符串
var str = "abcd";
var iterator = str[Symbol.iterator]();

// 来自Set对象
var set = new Set([1, 2, 3]);
var iterator = set[Symbol.iterator]();
var iterator = set.entries();
var iterator = set.keys();
var iterator = set.values();

// 来自Map对象
var map = new Map([['key1', 1], ['key2', 2]]);
var iterator = map[Symbol.iterator]();
var iterator = map.entries();
var iterator = map.keys();
var iterator = map.values();

// 来自arguments对象
function run(a, b) {
    var iterator = arguments[Symbol.iterator]();
    var iterator = run.arguments[Symbol.iterator]();
}

2. 原型方法

原型方法描述
next(): { value: any, done: boolean }进行一次迭代,返回结果对象,其中 value 表示值,done 表示是否迭代结束

3. 遍历迭代器

var iterator = new Set([1, 2, 3]).values();
// 对象本身是迭代器,或对象的[Symbol.iterator]()方法返回迭代器时
// 可用 for...of 遍历
for(value of iterator) {
    console.log(value); // 1 2 3
}
for(value of [1,2,3]) {
    console.log(value); // 1 2 3
}

// 通过while和迭代器next()方法进行遍历
let result = iterator.next();
while (!result.done) {
 	console.log(result.value); // 1 2 3
 	result = iterator.next();
}
Last Updated 2024/5/15 12:02:44