文章目录

  • 设计目的
  • 静态方法
    • 1. 取值:Reflect.get()
    • 2. 设值:Reflect.set()
    • 3. 判断:Reflect.has()
    • 4. 删除:Reflect.deleteProperty()
    • 5. 定义:Reflect.defineProperty()
    • 6. 原型:Reflect.getPrototypeOf()
    • 7. 原型:Reflect.setPrototypeOf()
    • 8. 绑定:Reflect.apply()
    • 9. new:Reflect.construct()
    • 10. 扩展:Reflect.isExtensible ()
    • 11. 禁扩:Reflect.preventExtensions()
    • 12. 属性:Reflect.ownKeys()
    • 13. 描述:Reflect.getOwnPropertyDescriptor()
  • Reflect 是为了操作对象而提供的新 API
  • Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。
  • 这些方法与proxy handlers (en-US)的方法相同。
  • Reflect不是一个函数对象,因此它是不可构造的。
  • 所以不能通过new运算符对其进行调用,或者将Reflect对象作为一个函数来调用。
  • Reflect的所有属性和方法都是静态的

设计目的

其一:

  • 将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上。
  • 现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect对象上。
  • 也就是说,从Reflect对象上可以拿到语言内部的方法。

其二:

  • 修改某些Object方法的返回结果,让其变得更合理。
// 老写法
try {// 定义一个数据,在无法定义属性时,会抛出一个错误Object.defineProperty(target, property, attributes);// success
} catch (e) {// failure
}// 新写法
if (Reflect.defineProperty(target, property, attributes)) { // 而Reflect则会返回false// success
} else {// failure
}

其三:

  • 让Object操作都变成函数行为。
// 老写法
// 判断assign属性是否在Object 对象中
'assign' in Object // true// 新写法
Reflect.has(Object, 'assign') // true

其四:

  • Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。
  • 这就让Proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。
  • 也就是说,不管Proxy怎么修改默认行为,你总可以在Reflect上获取默认行为。
// Proxy方法拦截target对象的属性赋值行为。
Proxy(target, {set: function(target, name, value, receiver) {// 它采用Reflect.set方法将值赋值给对象的属性,确保完成原有的行为,然后再部署额外的功能。var success = Reflect.set(target, name, value, receiver);if (success) {console.log('property ' + name + ' on ' + target + ' set to ' + value);}return success;}
});
// 每一个Proxy对象的拦截操作(get、delete、has)
// 内部都调用对应的Reflect方法,保证原生行为能够正常执行。
// 添加的工作,就是将每一个操作输出一行日志。
var loggedObj = new Proxy(obj, {get(target, name) {console.log('get', target, name);return Reflect.get(target, name);},deleteProperty(target, name) {console.log('delete' + name);return Reflect.deleteProperty(target, name);},has(target, name) {console.log('has' + name);return Reflect.has(target, name);}
});

静态方法

1. 取值:Reflect.get()

  • Reflect.get() 方法:获取对象身上某个属性的值(类似于 target[name]
/* 参数说明 */
1. target: 需要取值的目标对象
2. propertyKey: 需要获取的值的键值
3. receiver: 如果target对象中指定了getter,receiver则为getter调用时的this值。/* 语法 */
Reflect.get(target, propertyKey[, receiver])/* 返回值 */
1. 如果含有该属性,返回对应属性值
2. 如果没有该属性,则返回 undefined/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
var myObject = {foo: 1,bar: 2,get baz() {return this.foo + this.bar;},
}
Reflect.get(myObject, 'foofoo') // undefined
Reflect.get(myObject, 'bar')  // 2
Reflect.get(myObject, 'baz')  // 3// Object
var obj = { x: 1, y: 2 };
Reflect.get(obj, "x"); // 1// Array
var arr = ["zero", "one"];
Reflect.get(arr, 1); // "one"// 带有get处理程序的代理
var x = {p: 1};
var obj = new Proxy(x, {get(t, k, r) { return k + "bar"; }
});
Reflect.get(obj, "foo"); // "foobar"// 非对象
Reflect.get(1, 'foo') // 报错
Reflect.get(false, 'foo') // 报错
  • 如果 propertyKey 属性部署了读取函数(getter),则读取函数的this绑定receiver
var myObject = {foo: 1,bar: 2,get baz() {return this.foo + this.bar;},
};var myReceiverObject = {foo: 4,bar: 4,
};Reflect.get(myObject, 'baz', myReceiverObject) // 8

2. 设值:Reflect.set()

  • Reflect.set():以函数的方式给属性赋值。
/* 参数说明 */
1. target: 设置属性的目标对象。
2. propertyKey: 设置的属性的名称。
3. value: 设置的值。
4. receiver: 如果遇到 setter,receiver则为setter调用时的this值。/* 语法 */
Reflect.set(target, propertyKey, value[, receiver])/* 返回值 */
1. 如果设置成功,返回 true
2. 如果设置失败,则返回 false/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
var myObject = {foo: 1,set bar(value) {return this.foo = value;},
}myObject.foo // 1Reflect.set(myObject, 'foo', 2);
myObject.foo // 2Reflect.set(myObject, 'bar', 3)
myObject.foo // 3// Object
var obj = {};
Reflect.set(obj, "prop", "value"); // true
obj.prop; // "value"// Array
var arr = ["duck", "duck", "duck"];
Reflect.set(arr, 2, "goose"); // true
arr[2]; // "goose"// 它可以截断数组.
Reflect.set(arr, "length", 1); // true
arr; // ["duck"];// With just one argument, propertyKey and value are "undefined".
var obj = {};
Reflect.set(obj); // true
Reflect.getOwnPropertyDescriptor(obj, "undefined");
// { value: undefined, writable: true, enumerable: true, configurable: true }// 非对象类型
Reflect.set(1, 'foo', {}) // 报错
Reflect.set(false, 'foo', {}) // 报错
  • 如果propertyKey属性设置了赋值函数,则赋值函数的this绑定receiver
var myObject = {foo: 4,set bar(value) {return this.foo = value;},
};var myReceiverObject = {foo: 0,
};Reflect.set(myObject, 'bar', 1, myReceiverObject);
myObject.foo // 4
myReceiverObject.foo // 1

3. 判断:Reflect.has()

  • Reflect.has(): 判断一个对象是否存在某个属性(等同于 in 运算符)
/* 参数说明 */
1. target: 目标对象.
2. propertyKey: 属性名,需要检查目标对象是否存在此属性。/* 语法 */
Reflect.has(target, propertyKey)/* 返回值 */
1. 如果该属性存在,返回 true
2. 如果该属性不存在,则返回 false/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
var myObject = {foo: 1,
};// 旧写法
'foo' in myObject // true// 新写法
Reflect.has(myObject, 'foo') // trueReflect.has({x: 0}, "x"); // true
Reflect.has({x: 0}, "y"); // false// 如果该属性存在于原型链中,返回true
Reflect.has({x: 0}, "toString");// Proxy 对象的 .has() 句柄方法
obj = new Proxy({}, {has(t, k) { return k.startsWith("door"); }
});
Reflect.has(obj, "doorbell"); // true
Reflect.has(obj, "dormitory"); // false

4. 删除:Reflect.deleteProperty()

  • Reflect.deleteProperty():用于删除对象的属性(等同于delete obj[name]
/* 参数说明 */
1. target: 删除属性的目标对象。
2. propertyKey: 需要删除的属性的名称。/* 语法 */
Reflect.get(target, propertyKey)/* 返回值 */
1. 如果该属性不存在 或者 删除成功,返回 true
2. 如果该属性删除失败,则返回 false/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
const myObj = { foo: 'bar' };// 旧写法
delete myObj.foo;// 新写法
Reflect.deleteProperty(myObj, 'foo');var obj = { x: 1, y: 2 };
Reflect.deleteProperty(obj, "x"); // true
obj; // { y: 2 }var arr = [1, 2, 3, 4, 5];
Reflect.deleteProperty(arr, "3"); // true
arr; // [1, 2, 3, , 5]// 如果属性不存在,返回 true
Reflect.deleteProperty({}, "foo"); // true// 如果属性不可配置,返回 false
Reflect.deleteProperty(Object.freeze({foo: 1}), "foo"); // false

5. 定义:Reflect.defineProperty()

  • Reflect.defineProperty():用来为对象定义属性(等同于 Object.defineProperty
/* 参数说明 */
1. target: 目标对象。
2. propertyKey: 要定义或修改的属性的名称。
3. attributes: 要定义或修改的属性的描述。/* 语法 */
Reflect.defineProperty(target, propertyKey, attributes)/* 返回值 */
1. 如果该定义成功,返回 true
2. 如果该定义失败,则返回 false/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
function MyDate() {/*…*/
}// 旧写法
Object.defineProperty(MyDate, 'now', {value: () => Date.now()
});// 新写法
Reflect.defineProperty(MyDate, 'now', {value: () => Date.now()
});let obj = {}
Reflect.defineProperty(obj, 'x', {value: 7})  // true
obj.x                                         // 7

6. 原型:Reflect.getPrototypeOf()

  • Reflect.getPrototypeOf():用于读取对象的__proto__属性(等同于 Object.getPrototypeOf(obj)
/* 参数说明 */target: 获取原型的目标对象。/* 语法 */
Reflect.getPrototypeOf(target)/* 返回值 */
1. 给定对象的原型。
2. 如果给定对象没有继承的属性,则返回 null。/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
const myObj = new FancyThing();// 旧写法
Object.getPrototypeOf(myObj) === FancyThing.prototype;// 新写法
Reflect.getPrototypeOf(myObj) === FancyThing.prototype;Reflect.getPrototypeOf({}); // Object.prototype
Reflect.getPrototypeOf(Object.prototype); // null
Reflect.getPrototypeOf(Object.create(null)); // null
  • Object.getPrototypeOf的区别是:
// 如果参数为 Object,返回结果相同
Object.getPrototypeOf({})   // Object.prototype
Reflect.getPrototypeOf({})  // Object.prototype// 在 ES5 规范下,对于非 Object,抛异常
Object.getPrototypeOf('foo')   // Throws TypeError
Reflect.getPrototypeOf('foo')  // Throws TypeError// 在 ES2015 规范下,Reflect 抛异常, Object 强制转换非 Object
Object.getPrototypeOf('foo')   // String.prototype
Reflect.getPrototypeOf('foo')  // Throws TypeError

7. 原型:Reflect.setPrototypeOf()

  • Reflect.setPrototypeOf():方法用于设置目标对象的原型(等同于 Object.setPrototypeOf()
/* 参数说明 */
1. target: 设置原型的目标对象。
2. propertyKey: 对象的新原型(一个对象或 null)。/* 语法 */
Reflect.setPrototypeOf(target, prototype)/* 返回值 */
1. 原型设置成功,返回 true。
2. 原型设置失败,则返回 false。/* 异常 */
1. 如果目标值类型不是 Object ,抛出一个 TypeError。
2. prototype 既不是对象也不是 null,抛出一个 TypeError。
  • 示例:
const myObj = {};// 旧写法
Object.setPrototypeOf(myObj, Array.prototype);// 新写法
Reflect.setPrototypeOf(myObj, Array.prototype);
myObj.length // 0Reflect.setPrototypeOf({}, Object.prototype); // true// 它可以改变一个对象的 [[Prototype]] 为 null.
Reflect.setPrototypeOf({}, null); // true// 如果目标不是可扩展的,则返回false
Reflect.setPrototypeOf(Object.freeze({}), null); // false// 如果它导致原型链循环,则返回false。
var target = {};
var proto = Object.create(target);
Reflect.setPrototypeOf(target, proto); // false
  • 第一个参数情况:
/* 第一个参数非对象 */
Object.setPrototypeOf(1, {})
// 1Reflect.setPrototypeOf(1, {})
// TypeError: Reflect.setPrototypeOf called on non-object/* 第一个参数是undefined或null */
Object.setPrototypeOf(null, {})
// TypeError: Object.setPrototypeOf called on null or undefinedReflect.setPrototypeOf(null, {})
// TypeError: Reflect.setPrototypeOf called on non-object

8. 绑定:Reflect.apply()

  • Reflect.apply():用于绑定this对象后执行给定函数(等同于 Function.prototype.apply.call()
/* 参数说明 */
1. target: 目标函数。
2. thisArgument: target函数调用时绑定的this对象。
3. argumentsList: target函数调用时传入的实参列表,该参数应该是一个类数组的对象。值。/* 语法 */
Reflect.apply(target, thisArgument, argumentsList)/* 返回值 */
1. 返回值是调用完带着指定参数和 this 值的给定的函数后返回的结果。/* 异常 */
1. 如果 target 对象不可调用,抛出 TypeError。
  • 示例:
Reflect.apply(Math.floor, undefined, [1.75]);
// 1;Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
// "hello"Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;
// 4Reflect.apply("".charAt, "ponies", [3]);
// "i"
  • 一般来说,如果要绑定一个函数的this对象,可以这样写fn.apply(obj, args),
  • 但是如果函数定义了自己的apply方法,就只能写成Function.prototype.apply.call(fn, obj, args)
  • 采用Reflect对象可以简化这种操作。
const ages = [11, 33, 12, 54, 18, 96];// 旧写法
const youngest = Math.min.apply(Math, ages);
const oldest = Math.max.apply(Math, ages);
const type = Object.prototype.toString.call(youngest);// 新写法
const youngest = Reflect.apply(Math.min, Math, ages);
const oldest = Reflect.apply(Math.max, Math, ages);
const type = Reflect.apply(Object.prototype.toString, youngest, []);

9. new:Reflect.construct()

  • Reflect.construct():调用构造函数的方法(等同于 new target(...args)
/* 参数说明 */
1. target: 被运行的目标构造函数
2. argumentsList: 类数组,目标构造函数调用时的参数。
3. newTarget: 作为新创建对象的原型对象的constructor属性, 参考 new.target 操作符,默认值为target。/* 语法 */
Reflect.construct(target, argumentsList[, newTarget])/* 返回值 */
1. 以target(如果newTarget存在,则为newTarget)函数为构造函数,argumentList为其初始化参数的对象实例。/* 异常 */
1. 如果target或者newTarget不是构造函数,抛出TypeError,异常。
  • 示例:
function Greeting(name) {this.name = name;
}// new 的写法
const instance = new Greeting('张三');// Reflect.construct 的写法
const instance = Reflect.construct(Greeting, ['张三']);unction OneClass() {this.name = 'one';
}function OtherClass() {this.name = 'other';
}// 创建一个对象:
var obj1 = Reflect.construct(OneClass, args, OtherClass);// 与上述方法等效:
var obj2 = Object.create(OtherClass.prototype);
OneClass.apply(obj2, args);console.log(obj1.name); // 'one'
console.log(obj2.name); // 'one'console.log(obj1 instanceof OneClass); // false
console.log(obj2 instanceof OneClass); // falseconsole.log(obj1 instanceof OtherClass); // true
console.log(obj2 instanceof OtherClass); // true

10. 扩展:Reflect.isExtensible ()

  • Reflect.isExtensible():判断当前对象是否可扩展(等同于 Object.isExtensible
/* 参数说明 */
1. target: 检查是否可扩展的目标对象。/* 语法 */
Reflect.isExtensible(target)/* 返回值 */
1. 如果当前对象可扩展,返回 true
2. 如果当前对象不可扩展,则返回 false/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
const myObject = {};// 旧写法
Object.isExtensible(myObject) // true// 新写法
Reflect.isExtensible(myObject) // true// 新对象是可扩展的。
var empty = {};
Reflect.isExtensible(empty); // === true// 但这是可以改变的.
Reflect.preventExtensions(empty);
Reflect.isExtensible(empty); // === false// 根据定义,密封对象是不可扩展的.
var sealed = Object.seal({});
Reflect.isExtensible(sealed); // === false// 根据定义,冻结对象也是不可扩展的.
var frozen = Object.freeze({});
Reflect.isExtensible(frozen); // === false
  • 如果参数不是对象,Object.isExtensible会返回false,因为非对象本来就是不可扩展的,
  • Reflect.isExtensible会报错。
Object.isExtensible(1) // false
Reflect.isExtensible(1) // 报错

11. 禁扩:Reflect.preventExtensions()

  • Reflect.preventExtensions():阻止新属性添加到对象(等同于 Object.preventExtensions
/* 参数说明 */
1. target: 需要取值的目标对象阻止扩展的目标对象。/* 语法 */
Reflect.preventExtensions(target)/* 返回值 */
1. 如果设置成功,返回 true
2. 如果设置失败,则返回 false/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
var myObject = {};// 旧写法
Object.preventExtensions(myObject) // Object {}// 新写法
Reflect.preventExtensions(myObject) // true// 默认情况下,对象是可扩展的
var empty = {};
Reflect.isExtensible(empty); // === true// 但这是可以改变的
Reflect.preventExtensions(empty);
Reflect.isExtensible(empty); // === false
  • Object.preventExtensions的区别
// ES5 环境
Object.preventExtensions(1) // 报错// ES6 环境
Object.preventExtensions(1) // 1// ES5、ES6 环境
Reflect.preventExtensions(1) // 报错

12. 属性:Reflect.ownKeys()

  • Reflect.ownKeys():返回对象的所有属性(等同于 Object.getOwnPropertyNames+Object.getOwnPropertySymbols
/* 参数说明 */
1. target: 获取自身属性键的目标对象。/* 语法 */
Reflect.ownKeys(target)/* 返回值 */
1. 由目标对象的自身属性键组成的 Array。/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
var myObject = {foo: 1,bar: 2,[Symbol.for('baz')]: 3,[Symbol.for('bing')]: 4,
};// 旧写法
Object.getOwnPropertyNames(myObject)
// ['foo', 'bar']Object.getOwnPropertySymbols(myObject)
//[Symbol(baz), Symbol(bing)]// 新写法
Reflect.ownKeys(myObject)
// ['foo', 'bar', Symbol(baz), Symbol(bing)]

13. 描述:Reflect.getOwnPropertyDescriptor()

  • Reflect.getOwnPropertyDescriptor():获取指定属性的描述对象(等同于 Object.getOwnPropertyDescriptor
/* 参数说明 */
1. target: 需要寻找属性的目标对象。
2. propertyKey: 获取自己的属性描述符的属性的名称。/* 语法 */
Reflect.getOwnPropertyDescriptor(target, propertyKey)/* 返回值 */
1. 如果属性存在于给定的目标对象中,则返回属性描述符;
2. 否则,返回 undefined。/* 异常 */
1.  如果目标值类型不是 Object,则抛出一个 TypeError。
  • 示例:
Reflect.getOwnPropertyDescriptor({x: "hello"}, "x");
// {value: "hello", writable: true, enumerable: true, configurable: true}Reflect.getOwnPropertyDescriptor({x: "hello"}, "y");
// undefined
  • Object.getOwnPropertyDescriptor的区别
// 第一个参数不是对象,抛出错误,表示参数非法
Reflect.getOwnPropertyDescriptor("foo", 0);
// TypeError: "foo" is not non-null object// 第一个参数不是对象,不报错,返回 undefined,
Object.getOwnPropertyDescriptor("foo", 0);
// { value: "f", writable: false, enumerable: true, configurable: false }

【ES6】Reflect 反射相关推荐

  1. Proxy(代理,拦截器),Reflect(反射)

    Proxy(代理,拦截器),Reflect(反射) Proxy: 代理: var duixaing = {"name":"小胖","age" ...

  2. Proxy代理 和 Reflect反射(反射的是obj)的概念

    1. Proxy代理 // 供应商(原始对象)let obj = {time:'2018-01-03',name:'net',_r: "123"}// 创建代理商,传入obj数据l ...

  3. es6 --- Reflect的静态方法

    Reflect.get(target, name, receiver): 查找并返回 target对象的 name属性,若没有,返回undefined var myObject = {foo: 1,b ...

  4. GO语言reflect反射篇

    1.1 reflect反射是什么,为什么需要反射 GO 反射的意义:Go 语言的 ORM 库离不开它,Go 语言的 json 序列化库离不开它, fmt包字符串格式化离不开它,Go 语言的运行时更是离 ...

  5. 利用 Proxy 代理与 Reflect 反射实现 mv 模型视图,实现一个 打怪升级 的小游戏“勇士之战”

    利用 Proxy 代理与 Reflect 反射实现 mv 模型视图,多层数据动态渲染页面,模仿 vue3 双向绑定中 viewModel 核心功能,实现一个 打怪升级 的小游戏"勇士之战&q ...

  6. GO语言基础之reflect反射

    反射reflection 1. 反射可以大大的提高程序的灵活性,使得 interface{} 有更大的发挥余地 2. 反射使用 TypeOf 和 ValueOf 函数从接口中获取目标对象信息 3. 反 ...

  7. Go 语言编程 — reflect 反射机制

    目录 文章目录 目录 为什么需要反射? reflect 包 通过 reflect.TypeOf() 获取对象的反射类型 reflect.Type 通过 reflect.Elem() 获取指针所指向的对 ...

  8. golang reflect 反射 简介

    和Java语言一样,Go也实现运行时反射,这为我们提供一种可以在运行时操作任意类型对象的能力.比如我们可以查看一个接口变量的具体类型,看看一个结构体有多少字段,如何修改某个字段的值等等. TypeOf ...

  9. es6 Reflect对象的静态方法

    Reflect对象的静态方法 Reflect对象一共有 13 个静态方法. Reflect.apply(target, thisArg, args) Reflect.construct(target, ...

  10. es6 Reflect对象简介

    Reflect对象简介 Reflect对象与Proxy对象一样,也是 ES6 为了操作对象而提供的新 API.Reflect对象的设计目的有这样几个. (1) 将Object对象的一些明显属于语言内部 ...

最新文章

  1. PYthon3:函数实现“自动售卖机”功能
  2. 【C语言】20-static和extern关键字2-对变量的作用
  3. uygurqa输入法android,uygurqa输入法
  4. 为什么都在吹鸿蒙,真的是吹爆鸿蒙
  5. Python 参考文档
  6. 【转载】 quartus中调用modelsim仿真的方法
  7. ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍
  8. java minor gc_Java Minor发布计划再次进行了调整
  9. Java Annotation认知(包括框架图、详细介绍、示例说明)
  10. IT 已成为最疯狂的加班行业,没有之一
  11. 15.explain
  12. Leetcode之两棵二叉搜索树中的所有元素
  13. php mysql sum用法_mysql怎么使用sum()求id字段的和?
  14. Raki的统计学习方法笔记0x2章:感知机
  15. Everything搜索_使用方法
  16. python爬虫qq音乐_Python爬虫实战:采集全部QQ音乐歌曲
  17. 罗技G500游戏鼠标
  18. B站粉丝计数器 | ESP32轻松学(Arduino版)
  19. 买阿里云服务器多少钱,不同预算可购买的配置及价格汇总
  20. iphone ipad 为孩子创建 apple id

热门文章

  1. http状态码 200、404什么意思
  2. fei 正则表达式_正则表达式大爆料
  3. 计算机变成英语,win10系统下计算器界面变成英文界面了怎么办
  4. matlab 声明gpu,使用MATLAB轻松享受GPU的强大功能
  5. php 网站的多语言设置(IP地址区分国内国外)
  6. Postgresql计算月天数
  7. 一个高速公路交警的忠告
  8. debug and releas 不显示 调试窗口(DOS窗口/控制台)
  9. MATLAB彩色图像处理
  10. [POJ3537]Crosses and Crosses