系统对象
yuhuo2021-06-13JavaScriptJavaScript对象
提示
本文需与 《基础 / 对象详解》 一文相结合阅读
PropertyDescriptor 对象
1. 获取对象
// 查看单个自有属性描述对象
var descriptor = Object.getOwnPropertyDescriptor(obj, "key");
// 查看所有自有属性描述对象
var descriptor = Object.getOwnPropertyDescriptors(obj);
2. 对象属性
对象属性 | 类型 | 描述 |
---|---|---|
value | any | 属性值(数据属性) |
writable | boolean | 可写性(数据属性) |
get | Function | 取值方法(存取器属性) |
set | Function | 存值方法(存取器属性) |
enumerable | boolean | 可枚举性 |
configurable | boolean | 可配置性 |
注意
通过 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. 原型属性
原型属性 | 类型 | 描述 |
---|---|---|
constructor | Function | 当前对象的构造函数 |
__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.getOwnPropertySymbols | Object.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. 原型属性
对象属性 | 类型 | 描述 |
---|---|---|
name | string | 返回方法名 |
length | number | 返回形参个数 |
arguments | Arguments | 返回实参对象 [param1, param2..., callee: f],callee 代表方法对象本身(只有在方法体中有值) 同时方法体内自带 arguments 变量可以直接用 |
caller | Function | 返回执行方法的作用域对应的函数对象,如在全局作用域运行则返回 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. 对象属性
对象属性 | 类型 | 描述 |
---|---|---|
length | number | 返回实参个数 |
callee | Function | 返回当前方法对象 |
[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();
}