- var myObject = Object.create(null); // 这段代码比你想象得更加常见(尤其是在使用了新的 ES6 的类的时候)
- assert(myObject.hasOwnProperty === undefined);
- // 如果你想在 `myObject` 上使用 hasOwnProperty:
- Object.prototype.hasOwnProperty.call(myObject, 'foo');
- var s = Symbol('foo');
- var k = 'bar';
- var o = { [s]: 1, [k]: 1 };
- // 模拟 [[OwnPropertyKeys]]
- var keys = Object.getOwnPropertyNames(o).concat(Object.getOwnPropertySymbols(o));
- assert.deepEqual(keys, [k, s]);
- var ages = [11, 33, 12, 54, 18, 96];
- // Function.prototype 风格:
- var youngest = Math.min.apply(Math, ages);
- var oldest = Math.max.apply(Math, ages);
- var type = Object.prototype.toString.call(youngest);
- // Reflect 风格:
- var youngest = Reflect.apply(Math.min, Math, ages);
- var oldest = Reflect.apply(Math.max, Math, ages);
- var type = Reflect.apply(Object.prototype.toString, youngest);
- function totalNumbers() {
- return Array.prototype.reduce.call(arguments,
- function(total, next) {
- return total + next;
- },
- 0);
- }
- totalNumbers.apply = function() {
- throw new Error('Aha got you!');
- }
- totalNumbers.apply(null, [1, 2, 3, 4]); // 抛出 Error('Aha got you!');
- // ES5 中保证防御性的代码看起来很糟糕:
- Function.prototype.apply.call(totalNumbers, null, [1, 2, 3, 4]) === 10;
- // 你也可以这样做,但看起来还是不够整洁:
- Function.apply.call(totalNumbers, null, [1, 2, 3, 4]) === 10;
- // Reflect.apply 会是救世主!
- Reflect.apply(totalNumbers, null, [1, 2, 3, 4]) === 10;
- class Greeting {
- constructor(name) {
- this.name = name;
- }
- greet() {
- return Hello $ {
- this.name
- };
- }
- }
- // ES5 风格的工厂函数:
- function greetingFactory(name) {
- var instance = Object.create(Greeting.prototype);
- Greeting.call(instance, name);
- return instance;
- }
- // ES6 风格的工厂函数:
- function greetingFactory(name) {
- return Reflect.construct(Greeting, [name], Greeting);
- }
- // 如果省略第三个参数,那么默认绑定对象原型到第一个参数
- function greetingFactory(name) {
- return Reflect.construct(Greeting, [name]);
- }
- // ES6 下顺滑无比的线性工厂函数:
- const greetingFactory = (name) = >Reflect.construct(Greeting, [name]);
- function MyDate() {
- /*…*/
- }
- // 老的风格下,我们使用 Object.defineProperty 来定义一个函数的属性,显得很奇怪
- // (为什么我们不用 Function.defineProperty ?)
- Object.defineProperty(MyDate, 'now', {
- value: () = >currentms
- });
- // 新的风格下,语义就通畅得多,因为 Reflect 只是在做反射。
- Reflect.defineProperty(MyDate, 'now', {
- value: () = >currentms
- });
- var myObject = {};
- Object.defineProperty(myObject, 'hidden', {
- value: true,
- enumerable: false,
- });
- var theDescriptor = Reflect.getOwnPropertyDescriptor(myObject, 'hidden');
- assert.deepEqual(theDescriptor, { value: true, enumerable: true });
- // 老的风格
- var theDescriptor = Object.getOwnPropertyDescriptor(myObject, 'hidden');
- assert.deepEqual(theDescriptor, { value: true, enumerable: true });
- assert(Object.getOwnPropertyDescriptor(1, 'foo') === undefined)
- Reflect.getOwnPropertyDescriptor(1, 'foo'); // throws TypeError
- var myObj = { foo: 'bar' };
- delete myObj.foo;
- assert(myObj.hasOwnProperty('foo') === false);
- myObj = { foo: 'bar' };
- Reflect.deleteProperty(myObj, 'foo');
- assert(myObj.hasOwnProperty('foo') === false);
- var myObj = new FancyThing();
- assert(Reflect.getPrototypeOf(myObj) === FancyThing.prototype);
- // 老的风格
- assert(Object.getPrototypeOf(myObj) === FancyThing.prototype);
- Object.getPrototypeOf(1); // undefined
- Reflect.getPrototypeOf(1); // TypeError
- var myObj = new FancyThing();
- assert(Reflect.setPrototypeOf(myObj, OtherThing.prototype) === true);
- assert(Reflect.getPrototypeOf(myObj) === OtherThing.prototype);
- // 老的风格
- assert(Object.setPrototypeOf(myObj, OtherThing.prototype) === myObj);
- assert(Object.getPrototypeOf(myObj) === FancyThing.prototype);
- Object.setPrototypeOf(1); // TypeError
- Reflect.setPrototypeOf(1); // TypeError
- var myFrozenObj = new FancyThing();
- Object.freeze(myFrozenObj);
- Object.setPrototypeOf(myFrozenObj); // TypeError
- assert(Reflect.setPrototypeOf(myFrozenObj) === false);
- var myObject = {};
- var myNonExtensibleObject = Object.preventExtensions({});
- assert(Reflect.isExtensible(myObject) === true);
- assert(Reflect.isExtensible(myNonExtensibleObject) === false);
- Reflect.isExtensible(1); // 抛出 TypeError
- Reflect.isExtensible(false); // 抛出 TypeError
- // 使用 Object.isExtensible
- assert(Object.isExtensible(myObject) === true);
- assert(Object.isExtensible(myNonExtensibleObject) === false);
- // ES5 Object.isExtensible 语义
- Object.isExtensible(1); // 在老版本的浏览器下,会抛出 TypeError
- Object.isExtensible(false); // 在老版本的浏览器下,会抛出 TypeError
- // ES6 Object.isExtensible 语义
- assert(Object.isExtensible(1) === false); // 只工作在新的浏览器
- assert(Object.isExtensible(false) === false); // 只工作在新的浏览器
- var myObject = {};
- var myObjectWhichCantPreventExtensions = magicalVoodooProxyCode({});
- assert(Reflect.preventExtensions(myObject) === true);
- assert(Reflect.preventExtensions(myObjectWhichCantPreventExtensions) === false);
- Reflect.preventExtensions(1); // 抛出 TypeError
- Reflect.preventExtensions(false); // 抛出 TypeError
- // 使用 Object.preventExtensions
- assert(Object.preventExtensions(myObject) === true);
- Object.preventExtensions(myObjectWhichCantPreventExtensions); // throws TypeError
- // ES5 Object.preventExtensions 语义
- Object.preventExtensions(1); // 抛出 TypeError
- Object.preventExtensions(false); // 抛出 TypeError
- // ES6 Object.preventExtensions 语义
- assert(Object.preventExtensions(1) === 1);
- assert(Object.preventExtensions(false) === false);
- var myArray = [1, 2, 3];
- myArray[Symbol.enumerate] = function() {
- throw new Error('Nope!');
- }
- for (let item of myArray) { // error thrown: Nope!
- }
- for (let item of Reflect.enumerate(myArray)) {
- // 1 then 2 then 3
- }
- var myObject = {
- foo: 1,
- bar: 2,
- get baz() {
- return this.foo + this.bar;
- },
- }
- assert(Reflect.get(myObject, 'foo') === 1);
- assert(Reflect.get(myObject, 'bar') === 2);
- assert(Reflect.get(myObject, 'baz') === 3);
- assert(Reflect.get(myObject, 'baz', myObject) === 3);
- var myReceiverObject = {
- foo: 4,
- bar: 4,
- };
- assert(Reflect.get(myObject, 'baz', myReceiverObject) === 8);
- // 非对象将抛出错误
- Reflect.get(1, 'foo'); // 抛出 TypeError
- Reflect.get(false, 'foo'); // 抛出 TypeError
- // 老的风格下,静默返回 `undefined`:
- assert(1['foo'] === undefined);
- assert(false['foo'] === undefined);
- var myObject = {
- foo: 1,
- set bar(value) {
- return this.foo = value;
- },
- }
- assert(myObject.foo === 1);
- assert(Reflect.set(myObject, 'foo', 2));
- assert(myObject.foo === 2);
- assert(Reflect.set(myObject, 'bar', 3));
- assert(myObject.foo === 3);
- assert(Reflect.set(myObject, 'bar', myObject) === 4);
- assert(myObject.foo === 4);
- var myReceiverObject = {
- foo: 0,
- };
- assert(Reflect.set(myObject, 'bar', 1, myReceiverObject));
- assert(myObject.foo === 4);
- assert(myReceiverObject.foo === 1);
- // 非对象将抛出错误
- Reflect.set(1, 'foo', {}); // 抛出 TypeError
- Reflect.set(false, 'foo', {}); // 抛出 TypeError
- // 老的风格下,静默返回 `undefined`:
- 1['foo'] = {};
- false['foo'] = {};
- assert(1['foo'] === undefined);
- assert(false['foo'] === undefined);
- myObject = {
- foo: 1,
- };
- Object.setPrototypeOf(myObject, {
- get bar() {
- return 2;
- },
- baz: 3,
- });
- // 不使用 Reflect.has:
- assert(('foo' in myObject) === true);
- assert(('bar' in myObject) === true);
- assert(('baz' in myObject) === true);
- assert(('bing' in myObject) === false);
- // 使用 Reflect.has:
- assert(Reflect.has(myObject, 'foo') === true);
- assert(Reflect.has(myObject, 'bar') === true);
- assert(Reflect.has(myObject, 'baz') === true);
- assert(Reflect.has(myObject, 'bing') === false);
- var myObject = {
- foo: 1,
- bar: 2,
- [Symbol.for('baz')]: 3,
- [Symbol.for('bing')]: 4,
- };
- assert.deepEqual(Object.getOwnPropertyNames(myObject), ['foo', 'bar']);
- assert.deepEqual(Object.getOwnPropertySymbols(myObject), [Symbol.for('baz'), Symbol.for('bing')]);
- // 不使用 Reflect.ownKeys:
- var keys = Object.getOwnPropertyNames(myObject).concat(Object.getOwnPropertySymbols(myObject));
- assert.deepEqual(keys, ['foo', 'bar', Symbol.for('baz'), Symbol.for('bing')]);
- // 使用 Reflect.ownKeys:
- assert.deepEqual(Reflect.ownKeys(myObject), ['foo', 'bar', Symbol.for('baz'), Symbol.for('bing')]);
来源: https://juejin.im/post/5a0e66386fb9a04523417418