目录
- 1. 概述
- 2. Reflect对象静态方法
- 2.1 Reflect.get()
- 2.2 Reflect.set()
- 2.3 Reflect.has()
- 2.4 Reflect.deleteProperty()
- 2.5 Reflect.construct()
- 2.6 Reflect.getPrototypeOf()
- 2.7 Reflect.setPrototypeOf()
- 2.8 Reflect.apply()
- 2.9 Reflect.defineProperty()
- 2.10 Reflect.getOwnPropertyDescriptor()
- 2.11 Reflect.isExtensible ()
- 2.12 Reflect.preventExtensions()
- 2.13 Reflect.ownKeys ()
- 3 参考链接
1. 概述
Reflect
对象与Proxy
对象一样,也是 ES6 为了操作对象而提供的新 API。
Reflect
不是一个函数对象,它是不可构造的,而且Reflect
的所有属性和方法都是静态的。
Reflect
对象的设计目的有这样几个:
- 将
Object
对象的一些明显属于语言内部的方法,放到Reflect
对象上 - 修改某些
Object
方法的返回结果,让其变得更合理 - 让
Object
操作都变成函数行为 Reflect
对象的方法与Proxy
对象的方法一一对应,只要是Proxy
对象的方法,就能在Reflect
对象上找到对应的方法。能够让Proxy
对象调用对应的Reflect
方法,完成默认行为,作为修改行为的基础。
var person = {
name: "jidi"
}
var proxy = new Proxy(person, {
set(target, property, value, receiver) {
return Reflect.set(target, property, value, receiver);
}
})
person; // {name: "jidi"}
proxy.name = 1;
person; // {name: 1}
上面代码中,代理拦截对person
对象属性的写入行为,使用Reflect.set
方法确保能够正常写入属性。
2. Reflect对象静态方法
Reflect
对象一共有 13 个静态方法,它们都是跟Proxy
对象拦截操作是一一对应的。
Reflect.apply(target, thisArg, argumentsList)
Reflect.construct(target, argumentsList)
Reflect.get(target, property, receiver)
Reflect.set(target, property, value, receiver)
Reflect.defineProperty(target, property, descriptor)
Reflect.deleteProperty(target, property)
Reflect.has(target, property)
Reflect.ownKeys(target)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, property)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)
2.1 Reflect.get()
Reflect.get
方法可以从一个对象中取属性值。就如同属性访问器,但却是通过函数调用来实现。
语法
Reflect.get(target, property[, receiver])
参数
以下是传递给get
方法的参数:
- target:目标对象
- property:属性名
- receiver:如果
target
对象中指定了getter
,receiver
则为getter
调用时的this
值
返回值
返回目标对象对应属性的值。如果该属性不存在,返回undefined
。
约束
如果目标值(target
)类型不是Object
,抛出一个 TypeError
。
示例一
var person = {
name: "jidi",
age: 22
}
Reflect.get(person, "name"); // "jidi"
Reflect.get(person, "sex"); // undefined
示例二
var perosn = {
name: "jidi",
age: 22,
get info() { // 定义getter
return this.name + this.age;
}
}
var receiver = {
name: "基地",
age: 23
}
Reflect.get(person, "info", receiver); // "基地23"
上面代码演示了第三个参数receiver
的使用。
示例三
Reflect.get(true, 'toString'); // Uncaught TypeError: Reflect.get called on non-object at Object.get
上面代码演示了违反约束的情况。
2.2 Reflect.set()
Reflect.set
方法允许给对象属性赋值并且是以函数的方式。
语法
Reflect.set(target, property, value[, receiver]);
参数
以下是传递给set
方法的参数:
- target:设置属性的目标对象
- property:设置的属性的名称
- value:设置的值
- receiver:如果遇到
setter
,receiver
则为setter
调用时的this
值。
返回值
返回一个布尔值,表示属性是否设置成功。
约束
如果target
不是一个对象,会报错TypeError
。
示例一
var person = {};
Reflect.set(person, "name", "jidi");
person.name; // "jidi"
示例二
var person = {
name: "jidi",
age: 22,
set info(value) {
console.info(this === receiver)
this.name = value;
}
};
var receiver = {
name: "基地"
}
Reflect.set(person, "info", "jidi", receiver); // true
receiver.name; // "jidi"
上面代码,person
对象设置了setter
,当调用setter
时,setter
内部this
会指向receiver
。
示例三
Reflect.set(1, 'name', {}) // Uncaught TypeError: Reflect.set called on non-object at Object.set
上面代码演示了违反约束的情况。
2.3 Reflect.has()
Reflect.has
用于检查一个对象是否拥有某个属性, 相当于in
操作符 ,但是是以函数的形式。
语法
Reflect.has(target, property);
参数
以下是传递给has
方法的参数:
- target:目标对象
- property:属性名
返回值
返回一个布尔值,表示对象是否拥有某个属性。
约束
如果目标对象并非Object
类型,抛出TypeError
。
示例
var person = {
name: "jidi"
}
Reflect.has(person, "name"); // true
Reflect.has(person, "age"); // false
2.4 Reflect.deleteProperty()
Reflect.deleteProperty
用于删除对象属性,相当于delete obj[property]
。
语法
Reflect.deleteProperty(target, property);
参数
以下是传递给deleteProperty
方法的参数:
- target:目标对象
- property:属性名
返回值
返回一个布尔值,表示对象属性是否被删除。
约束
如果目标对象并非Object
类型,抛出TypeError
。
示例
var person = {
name: "jidi",
age: 22
}
Reflect.deleteProperty(person, 'name'); // true
person; // {age: 22}
// 如果属性不存在,返回 true
Reflect.deleteProperty({}, "name"); // true
2.5 Reflect.construct()
Reflect.construct
方法等同于new target(...args)
,这提供了一种不使用new
,来调用构造函数的方法。
语法
Reflect.construct(target, argumentsList[, newTarget]);
参数
以下是传递给construct
方法的参数:
- target:被运行的目标构造函数
- argumentsList:目标构造函数调用时的参数
- newTarget :新创建对象的原型对象, 默认值为
target
返回值
返回一个实例对象。
约束
如果target
或者newTarget
不是构造函数,抛出TypeError
异常。
示例
// 定义构造函数
function Person(name, sex, age) {
if(!new.target) {
return new Person(name, sex, age);
}
this.name = name;
this.sex = sex;
this.age = age
}
// 使用new命令写法
var p1 = new Person("jidi", "男", 22);
p1; // Person {name: "jidi", sex: "男", age: 22}
// 使用Reflect.construct()静态方法
var p2 = Reflect.construct(Person, ["基地", "男", 23]);
p2; // Person {name: "jidi", sex: "男", age: 22}
2.6 Reflect.getPrototypeOf()
Reflect.getPrototypeOf
返回指定对象的原型 (即内部的 [[Prototype
]] 属性的值) 。
语法
Reflect.getPrototypeOf(target);
参数
以下是传递给getPrototypeOf
方法的参数:
- target:目标对象
返回值
给定对象的原型。如果给定对象没有继承的属性,则返回 null
。
约束
如果 target
不是 Object
,抛出一个 TypeError
异常。
演示
var person = { // 普通对象
name:"jidi"
}
var proto = { // 原型对象
sleep() {
console.info("sleeping....")
}
}
// 设置原型对象
Object.setPrototypeOf(person,proto);
Reflect.getPrototypeOf(person) === proto; // true
2.7 Reflect.setPrototypeOf()
Reflect.setPrototypeOf
方法改变指定对象的原型。
语法
Reflect.setPrototypeOf(target, prototype);
参数
以下是传递给setPrototypeOf
方法的参数:
- target:设置原型的目标对象
- prototype:对象的新原型(一个对象或
null
)
返回值
返回一个 Boolean
值表明原型是否已经成功设置。
约束
如果target
不是Object
,或 prototype
既不是对象也不是 null
,抛出一个 TypeError
异常。
示例
var person = {};
// 设置原型,成功返回true
Reflect.setPrototypeOf(person , Array.prototype); // true
person.length; // 0
// target不能为null或undefined
Object.setPrototypeOf(null, {}); // Uncaught TypeError: Object.setPrototypeOf called on null or undefined at Function.setPrototypeOf
2.8 Reflect.apply()
静态方法 Reflect.apply()
通过指定的参数列表发起对目标(target
)函数的调用。
语法
Reflect.apply(target, thisArgument, argumentsList);
参数
以下是传递给apply
方法的参数:
- target:目标函数
- thisArgument:target函数调用时绑定的this对象。
- argumentsList:target函数调用时传入的实参列表,该参数应该是一个类数组的对象。
返回值
返回值是调用完带着指定参数和this
值的给定的函数后返回的结果。
约束
如果 target
对象不可调用,抛出 TypeError
。
示例
// 旧写法
Function.prototype.apply.call(Math.floor, Math, [1.23]); // 1
// 或者
Math.floor.apply(Math, [1.23]); // 1
// 新写法
Reflect.apply(Math.floor, Math, [1.23]); // 1
2.9 Reflect.defineProperty()
静态方法 Reflect.defineProperty()
基本等同于 Object.defineProperty()
方法,唯一不同是返回 Boolean
值。
语法
Reflect.defineProperty(target, property, attributes)
参数
以下是传递给defineProperty
方法的参数:
- target:目标对象
- property:要定义或修改的属性的名称
- attributes:要定义或修改的属性的描述
返回值
返回Boolean
值,表示属性是否被成功定义。
约束
如果target
不是 Object
,抛出一个 TypeError
。
示例
var person = {};
// 设置对象属性
Reflect.defineProperty(person, "name", {
value: "jidi",
enumerable: true
})
person; // {name: "jidi"}
Object.getOwnPropertyDescriptor(person, "name"); // {value: "jidi", writable: false, enumerable: true, configurable: false}
2.10 Reflect.getOwnPropertyDescriptor()
Reflect.getOwnPropertyDescriptor
基本等同于Object.getOwnPropertyDescriptor
,用于得到指定属性的描述对象。
语法
Reflect.getOwnPropertyDescriptor(target, property);
参数
- target:需要寻找属性的目标对象
- property:获取自己的属性描述符的属性的名称。
返回值
如果属性存在于给定的目标对象中,则返回属性描述对象;否则,返回 undefined
。
约束
如果目标对象不是 Object
,抛出一个 TypeError
。
示例
var person = {
name: "jidi"
}
Reflect.getOwnPropertyDescriptor(person, "name"); // {value: "jidi", writable: false, enumerable: true, configurable: false}
2.11 Reflect.isExtensible ()
Reflect.isExtensible
方法对应Object.isExtensible
,返回一个布尔值,表示当前对象是否可扩展。
语法
Reflect.isExtensible(target);
参数
- target:检查是否可扩展的目标对象。
返回值
返回一个Boolean
值表明该对象是否可扩展。
约束
如果目标对象不是 Object
,抛出一个 TypeError
。
示例
var p= {};
Reflect.isExtensible(p); // true
Reflect.preventExtensions(p);
Reflect.isExtensible(p); // false
2.12 Reflect.preventExtensions()
Reflect.preventExtensions
对应Object.preventExtensions
方法,用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操作成功。
语法
Reflect.preventExtensions(target);
参数
- target:阻止扩展的目标对象。
返回值
返回一个Boolean
值表明目标对象是否成功被设置为不可扩展。
约束
如果目标对象不是 Object
,抛出一个 TypeError
。
示例
var p= {};
Reflect.isExtensible(p); // true
Reflect.preventExtensions(p);
Reflect.isExtensible(p); // false
2.13 Reflect.ownKeys ()
Reflect.ownKeys
方法用于返回一个由目标对象自身的属性组成的数组。
语法
Reflect.ownKeys(target);
参数
- target:获取自身属性的目标对象。
返回值
由目标对象的自身属性组成的数组。
约束
如果目标对象不是 Object
,抛出一个 TypeError
。
示例
var person= {
name: "jidi",
age: 22,
[Symbol.for('x')]: 3,
[Symbol.for('y')]: 4,
};
Reflect.ownKeys(person); // ["name", "age", Symbol(x), Symbol(y)]
3 参考链接
本篇博文是我自己学习笔记,原文请参考:ECMAScript 6 入门,MDN网站。
如有问题,请及时指出!
欢迎沟通交流,邮箱:[email protected]。