Explain Reflect in detail: the similarities and differences between Reflect and Object, some built-in methods of Reflect, and method attention points

Reflect

Reflect has some internal methods of the Object object, and some methods will be deployed on the Object object and the Reflect object at the same time, that is to say, the methods existing on the Object object can also be accessed through Reflect.
In the case of Reflect alone, it can be understood that Reflect inherits some built-in methods of Object and provides optimization

Some methods on the Object object have some defects. For example, an error will be thrown when a getter or setter is performed on a non-writable or non-enumerable property on Object.defineProperty. For this error, we need try catch to catch it, and Reflect.defineProperty will throw false to indicate that the operation failed (Reflect will throw true and false to indicate whether the operation is successful or not for the operation of the object).
Object

const obj = { name : 'undefeated east' }
Object.defineProperty(obj,'age',{
    value : 100,
    writable : true,  // read only
    configurable : false  // Cannot be deleted and modified
})

Object.defineProperty(obj,'age',{
    get(){ return 200 }
})
console.log(obj.age); //  TypeError : Cannot redefine property: age
// Error, cannot redefine attribute

Reflect

const obj2 = { name : 'western defeat' }
Object.defineProperty(obj2,'age',{
    value : 100,
    writable : true,  // read only
    configurable : false  // Cannot be deleted and modified
})

let status = Reflect.defineProperty(obj2,'age',{
    get(){ return }
})

console.log(status); //  false
console.log(obj2.age); // 100
// Reflect will throw false to indicate that the operation failed

Some operations of Object are imperative

let obj3 = {
    name : 'undefeated east',
    age : 100
}

console.log('name' in obj3);  // true
console.log(delete obj3.age);  // true
console.log(obj3);  // {name: 'Eastern Undefeated'}

The operation of Reflect is functional

let obj4 = {
    name : 'western defeat',
    age : 100
}

console.log(Reflect.has(obj4,'name'));  // true
console.log(Reflect.deleteProperty(obj4,'age')); // true
console.log(obj4);  // {name: 'Western Seeking Defeat'}

From the above case, we can know that some methods inside Object can be accessed on Reflect. The Reflect object has 13 static methods in total, as follows:

1,Reflect.apply(target, thisArg, args)

2,Reflect.construct(target, args)

3,Reflect.get(target, name, receiver)

4,Reflect.set(target, name, value, receiver)

5,Reflect.defineProperty(target, name, desc)

6,Reflect.deleteProperty(target, name)

7,Reflect.has(target, name)

8,Reflect.ownKeys(target)

9,Reflect.isExtensible(target)

10,Reflect.preventExtensions(target)

11,Reflect.getOwnPropertyDescriptor(target, name)

12,Reflect.getPrototypeOf(target)

13,Reflect.setPrototypeOf(target, prototype)

The following is an explanation of the use of some of the above methods

Reflect.get(target,name,receiver)

Reglect.get() has three parameters, which are

 1,`target` : target
 2,`name`: object properties
 3,`receiver`:  proxy object (can be ignored)

Function: Find and return the name attribute of the target object, if the attribute does not exist, return undefined

let o = {
    name : 'East',
    text : 'undefeated'
}
console.log(Reflect.get(o,'name'));  // East

Reflect.set(target, name, value, receiver)

It is used to set the name attribute of the target object to be equal to the value. If the modification is successful, it returns true, and if it fails, it returns false

  let o2 = {
    name : 'Introduction to Art',
  }
// If the setting here is not modifiable, then back will output false, and the value of price will be undefined
//   Object.defineProperty(o2,'price',{
//     configurable : false
//   })
  let back = Reflect.set(o2,'price',100)
  console.log(back); // true
  console.log(o2);  // {name: 'Introduction to Art', price: 100}

Reflect.has(obj, name)

Equivalent to the in operator in Object, it judges whether the current attribute exists in the target object, true exists, false does not exist

let o3 = {
    name : 'History of Chinese Arts and Crafts'
}

console.log('name' in o3);  // true
console.log(Reflect.has(o3,'name')); // true

If the first parameter of Reflect.has is not an object, an error will be reported

Reflect.deleteProperty(obj, name)

Equivalent to the delete operation of Object: delete obj.name, used to delete the properties of the object

let o4 = {
    book : 'Windy Grass',
    text : 'a helping hand'
}
// Object
delete o4.book
console.log(o4);  // {text: 'A hand'}
// Reflect
Reflect.deleteProperty(o4,'text')
console.log(o4);  // {}

Reflect.construct(target, args)

Equivalent to new class(params), Reflect here can create a method to call the constructor without new

function Person(name){
    this.name = name
}

// new wording
let onNew = new Person('East')

// Reflect.construct
let onNew2 = Reflect.construct(Person,['undefeated'])

The first parameter of Reflect.construct is not a function and an error will be reported

Reflect.getPrototypeOf(obj)

Corresponding to Object.getPrototypeOf(obj), used to read the __proto__ attribute of the object

let o5 = new String()

// Object.getPrototypeOf()
console.log(Object.getPrototypeOf(o5) == String.prototype); // true

// Reflect.getPrototypeOf()
console.log(Reflect.getPrototypeOf(o5) == String.prototype); // true

Reflect.setPrototypeOf(obj, newProto)

Corresponds to Object.setPrototypeOf(obj, newProto), which is used to set the prototype of the target object (prototype)

let o6 = {}
Reflect.setPrototypeOf(o6,Array.prototype)
console.log(o6.length);  // 0

Reflect.defineProperty(target, propertyKey, attributes)

Equivalent to Object.defineProperty, Reflect.defineProperty() is used to define the properties of the object.

let o7 = {
    name : 'undefeated east'
}

Reflect.defineProperty(o7,'age',{
    value : 100,
    configurable: true,
    enumerable : true,
    writable : true
})
console.log(o7);  // {name: 'Eastern Invincible', age: 100}

If the first parameter of Reflect.defineProperty() is not an object, an error will be thrown.

Reflect.getOwnPropertyDescriptor(target, propertyKey)

Corresponds to Object.getOwnPropertyDescriptor, which is used to obtain the description object of the specified property

let o8 = {
    name : 'undefeated east'
}

Reflect.defineProperty(o8,'age',{
    value : 100,
    configurable: true,
    enumerable : true,
    writable : true
})

let back8 = Reflect.getOwnPropertyDescriptor(o8,'age')
console.log(back8);  // {value: 100, writable: true, enumerable: true, configurable: true}

If the first parameter of Reflect.getOwnPropertyDescriptor() is not an object, an error will be thrown.

Reflect.isExtensible (target)

Equivalent to Object.isExtensible, returns a Boolean value indicating whether the current object is extensible

let o9 = {}
let back9 = Reflect.isExtensible(o9)
console.log(back9);  // true

If the parameter is not an object, an error will be reported, and non-objects are inherently non-extensible

console.log(Reflect.isExtensible(100));  // report error

Reflect.preventExtensions(target)

Equivalent to Object.preventExtensions, which can make the target object become non-extensible, and return a Boolean value to indicate whether the setting is successful

let b = {}
let info =  Reflect.preventExtensions(b)
console.log(info); // true
console.log(Reflect.isExtensible(b)); // false

If the parameter is not an object, an error will be reported

Reflect.ownKeys (target)

Used to return all properties of the target object, including Symbol

let address = Symbol.for('Wuhan')
let b2 = {
    name : 'undefeated east',
    age : 100,
    [address] : 'World City Plaza'
}

let info2 = Reflect.ownKeys(b2)
console.log(info2); // ['name', 'age', Symbol( Wuhan)]

If the parameter of Reflect.ownKeys () is not an object, an error will be reported

Reflect.apply(func, thisArg, args)

Used to execute the given function after binding this object. If you want to bind a this object to the number of rows, you can use the apply method, but the shareholding function defines its own apply method, so it can only be written as Function.prototype.apply.call(fn, obj, args) method nesting , while Reflect can be simplified.

 let arr = [1,2,3,4,5,6,7]
 
 // old way
 let a = Math.min.apply( Math, arr)
 let a2 = Math.max.apply( Math, arr)
 let a3 = Object.prototype.toString.call(a)
 console.log(a);   // 1
 console.log(a2);  // 7
 console.log(a3);  // [object Number]

 // new wording
 let a4 = Reflect.apply( Math.min, Math, arr)
 let a5 = Reflect.apply( Math.max, Math, arr)
 let a6 = Reflect.apply( Object.prototype.toString, a4, [])
 console.log(a4);  // 1
 console.log(a5);  // 7
 console.log(a6);  // [object Number]
apply method:
Function.apply(obj,args)The method accepts two parameters  
obj: This object will replace Function class this object
args: This is the array, which will be passed as a parameter Function

In fact, some static functions on Reflect correspond to the methods available on Object before ES2015. Although some methods look similar in behavior, there are often some subtle differences between them. The Reflect object has a total of 13 static methods. The following table details the differences between the methods available on the Object and Reflect API s. Note that if a method does not exist in the API, it is marked as N/A.

methodObjectReflect
defineProperty()Object.defineProperty() returns the object passed to the function. Returns TypeError if the property is not successfully defined on the object.Reflect.defineProperty() returns true if the property is defined on the object, false otherwise.
defineProperties()Object.defineProperties() returns the object passed to the function. Returns TypeError if the property is not successfully defined on the object.N/A
set()N/AReflect.set() returns true if the property was successfully set on the object, false otherwise. If the target is not an Object, a TypeError is thrown
get()N/AReflect.get() returns the value of the property. If target is not Object, TypeError is thrown.
deleteProperty()N/AReflect.deleteProperty() returns true if the property is deleted from the object, false otherwise.
getOwnPropertyDescriptor()Object.getOwnPropertyDescriptor() returns the property descriptor for the given property if present on the object argument passed in, or undefined if not present.Reflect.getOwnPropertyDescriptor() Returns the property descriptor for the given property if the given property exists on the object. Returns undefined if it does not exist, or TypeError if anything other than an object (primitive value) is passed in as the first argument
getOwnPropertyDescriptors()Object.getOwnPropertyDescriptors() returns an object containing property descriptors for each passed in object. Returns an empty object if the passed in object has no owning property descriptors.N/A
getPrototypeOf()Object.getPrototypeOf() returns the prototype of the given object. Returns null if there is no inherited prototype. Raises TypeError for non-objects in ES5, but coerces to non-objects in ES2015.Reflect.getPrototypeOf() returns the prototype of the given object. Returns null if there is no inherited prototype and throws TypeError for non-objects.
setPrototypeOf()If the object's prototype is successfully set, Object.setPrototypeOf() returns the object itself. Throws TypeError if the prototype set is not Object or null, or if the prototype of the object being modified is not extendable.Reflect.setPrototypeOf() returns true if the prototype was successfully set on the object, false otherwise (including if the prototype is not extensible). Throws TypeError if the passed in target is not Object, or if the set prototype is not Object or null.
isExtensible()Object.isExtensible() returns true if the object is extensible, false otherwise. In ES5 throws a TypeError if the first argument is not an object (a primitive value). In ES2015, it will be coerced to non-extensible plain objects and return false.Reflect.isExtensible() returns true if the object is extensible, false otherwise. If the first argument is not an object (a primitive value), TypeError is thrown.
preventExtensions()Object.preventExtensions() returns an object that is set to be non-extensible. TypeError is thrown in ES5 if the argument is not an object (is a primitive value). In ES2015, the parameter is treated as a non-extensible ordinary object, and the object itself is returned.Reflect.preventExtensions() returns true if the object has become non-extendable, false otherwise. If the argument is not an object (is a primitive value), TypeError is thrown.
keys()Object.keys() returns an array of strings that map to the target object's own (enumerable) property keys. Throw TypeError in ES5 if target is not an object, but coerce non-object targets to objects in ES2015N/A
ownKeys()N/AReflect.ownKeys() returns an array of property names that map to the target object's own property keys. If target is not Object, TypeError is thrown.

Links to sources for data comparison in the above tables: Comparing Reflect and Object methods

Case source code: https://gitee.com/wang_fan_w/es6-science-institute

If you think this article is helpful to you, please light up the star

Tags: Javascript Vue.js Front-end ecmascript-6

Posted by dellvostro on Tue, 21 Feb 2023 21:22:48 +0530