SOURCE

/**
 * Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。
 * 这些方法与proxy handlers (en-US)的方法相同。
 * Reflect不是一个函数对象,因此它是不可构造的。
 * 与大多数全局对象不同Reflect并非一个构造函数,所以不能通过new运算符对其进行调用,
 * 或者将Reflect对象作为一个函数来调用。Reflect的所有属性和方法都是静态的(就像Math对象)。
 * Reflect 对象提供了以下静态方法,这些方法与proxy handler methods (en-US)的命名相同.
 * 其中的一些方法与 Object相同, 尽管二者之间存在 某些细微上的差别 .
 */
// console.log(Object.prototype.isPrototypeOf(Reflect));


/**
 * Reflect.apply()
 * 静态方法 Reflect.apply() 通过指定的参数列表发起对目标(target)函数的调用。
 * target
 * 目标函数。
 * thisArgument
 * target函数调用时绑定的this对象。
 * argumentsList
 * target函数调用时传入的实参列表,该参数应该是一个类数组的对象。
 * 返回值是调用完带着指定参数和 this 值的给定的函数后返回的结果。
 * 如果 target 对象不可调用,抛出 TypeError。
 */
// Reflect.apply(target, thisArgument, argumentsList)
// console.log(Reflect.apply(String.prototype.charAt, 'apple', [2]));//p

/**
 * Reflect.construct()
 * Reflect.construct() 方法的行为有点像 new 操作符 构造函数 , 
 * 相当于运行 new target(...args).
 * target
 * 被运行的目标构造函数
 * argumentsList
 * 类数组,目标构造函数调用时的参数。
 * newTarget 可选
 * 作为新创建对象的原型对象的constructor属性, 参考 new.target 操作符,默认值为target。
 * 以target(如果newTarget存在,则为newTarget)函数为构造函数,
 * argumentList为其初始化参数的对象实例。
 * 如果target或者newTarget不是构造函数,抛出TypeError,异常。
 */
//Reflect.construct(target, argumentsList[, newTarget])
function oneClass() {
    this.name = 'one';
    // console.log(new.target);
};
function twoClass(...args) {
    // console.log('enter', args)
    this.name = 'two' + args[3];
    // console.log(new.target);
};
const obj1 = Reflect.construct(twoClass, [1, 2, 3, 4, 5], oneClass);//enter,[1,2,3,4,5]
// console.log(obj1, obj1 instanceof oneClass);// {name:'two4'},true
const obj2 = Reflect.construct(twoClass, [1, 2, 3, 4, 5]);//enter,[1,2,3,4,5]
// console.log(obj2, obj2 instanceof twoClass); //{ name: 'two4' }, true
//当使用Object.create()和Function.prototype.apply()时,
//如果不使用new操作符调用构造函数,构造函数内部的new.target值会指向undefined。
//当调用Reflect.construct()来创建对象,
//new.target值会自动指定到target(或者newTarget,前提是newTarget指定了)。


/**
 * Reflect.defineProperty()
 * 静态方法 Reflect.defineProperty() 基本等同于 Object.defineProperty() 方法,
 * 唯一不同是返回 Boolean 值。
 * target
 * 目标对象。
 * propertyKey
 * 要定义或修改的属性的名称。
 * attributes
 * 要定义或修改的属性的描述。
 * Boolean 值指示了属性是否被成功定义。
 * 如果target不是 Object,抛出一个 TypeError。
 * => boolean
 */
//Reflect.defineProperty(target, propertyKey, attributes)
const obj3 = {};
const target3 = Reflect.defineProperty(obj3, 'name', {
    value: 'obj3',
    writable: true,
    enumerable: true,
    configurable: true
});
// console.log(target3, obj3);//true, {name: 'obj3' }
// Object.defineProperty 方法,如果成功则返回一个对象,否则抛出一个 TypeError 。
// 另外,当定义一个属性时,你也可以使用 try...catch 去捕获其中任何的错误。
// 而因为 Reflect.defineProperty 返回 Boolean 值作为成功的标识,所以只能使用 if...else 

/**
 * Reflect.deleteProperty()
 * 静态方法 Reflect.deleteProperty() 允许用于删除属性。它很像 delete operator ,但它是一个函数。
 * Boolean 值表明该属性是否被成功删除。
 * => boolean
 */
//Reflect.deleteProperty(target, propertyKey)
const obj4 = {
    name: 'obj4',
    age: '4'
};
const target4 = Reflect.deleteProperty(obj4, 'age');
// console.log(obj4, target4);//{name:"obj4"},true


/**
 * Reflect.get()
 * Reflect.get()方法与从 对象 (target[propertyKey]) 中读取属性类似,
 * 但它是通过一个函数执行来操作的。
 * target
 * 需要取值的目标对象
 * propertyKey
 * 需要获取的值的键值
 * receiver
 * 如果target对象中指定了getter,receiver则为getter调用时的this值。
 * Reflect.get方法允许你从一个对象中取属性值。就如同属性访问器 语法,但却是通过函数调用来实现。
 * => propertyValue
 */
//Reflect.get(target, propertyKey[, receiver])
const obj5 = {
    name: 'obj5',
    age: 5
};
const proxy5 = new Proxy(obj5, {
    get(t, p, r) {
        return t[p];
    }
});
const target5 = Reflect.get(proxy5, 'name');
// console.log(target5, proxy5, obj5);

/**
 * Reflect.getOwnPropertyDescriptor()
 * 静态方法 Reflect.getOwnPropertyDescriptor() 与 Object.getOwnPropertyDescriptor() 方法相似。
 * 如果在对象中存在,则返回给定的属性的属性描述符。否则返回 undefined。 
 * target
 * 需要寻找属性的目标对象。
 * propertyKey
 * 获取自己的属性描述符的属性的名称。
 * 如果属性存在于给定的目标对象中,则返回属性描述符;否则,返回 undefined.
 * => propertyDescriptor / undefined
 */
//Reflect.getOwnPropertyDescriptor(target, propertyKey)
const obj6 = {
    name: 'obj6',
    age: '6',
};
const target6 = Reflect.getOwnPropertyDescriptor(obj6, 'name');
const targetO6 = Object.getOwnPropertyDescriptor('123', 0);
// console.log(target6, targetO6);

//Reflect.getOwnPropertyDescriptor方法返回一个属性描述符,如果给定的属性存在于对象中,否则返回 undefined 。 
//与  Object.getOwnPropertyDescriptor() 的唯一不同在于如何处理非对象目标。
// 如果该方法的第一个参数不是一个对象(一个原始值),那么将造成 TypeError 错误。
// 而对于 Object.getOwnPropertyDescriptor,非对象的第一个参数将被强制转换为一个对象处理。


/**
 * Reflect.getPrototypeOf()
 * 静态方法 Reflect.getPrototypeOf() 与 Object.getPrototypeOf() 方法几乎是一样的。
 * 都是返回指定对象的原型(即内部的 [[Prototype]] 属性的值)。
 * 给定对象的原型。如果给定对象没有继承的属性,则返回 null。
 * => target.prototype / null
 */
//Reflect.getPrototypeOf(target)
const obj7 = {
    name: 'obj7',
    age: 7
};
const target7 = Reflect.getPrototypeOf(obj7);
// console.log(target7 === Object.prototype, Object.prototype.isPrototypeOf(obj7));

/**
 * Reflect.has()
 * 静态方法 Reflect.has() 作用与 in 操作符 相同。
 * 一个 Boolean 类型的对象指示是否存在此属性。
 * => boolean
 */
//Reflect.has(target, propertyKey)
const obj8 = {
    name: 'obj8',
    age: 8
};
const obj8Prototype = {
    level: 1
};
Object.setPrototypeOf(obj8, obj8Prototype);
// console.log(obj8Prototype.isPrototypeOf(obj8), Reflect.has(obj8, 'level'));

/**
 * Reflect.isExtensible()
 * 静态方法 Reflect.isExtensible() 判断一个对象是否可扩展 (即是否能够添加新的属性)。
 * 与它 Object.isExtensible() 方法相似,但有一些不同,
 * 详情可见 与 Object.isExtensible() 的不同点。
 * target
 * 检查是否可扩展的目标对象。
 * 返回一个 Boolean 值表明该对象是否可扩展。
 * => boolean
 */
//Reflect.isExtensible(target)
const obj9 = {
    name: 'obj9',
    age: 9
};
Object.preventExtensions(obj9);
obj9.level = '1';
obj9.name = 'change';
const target9 = Reflect.isExtensible(obj9);
// console.log(obj9, target9);

//如果该方法的第一个参数不是一个对象(原始值),那么将造成一个 TypeError 异常。
//对于 Object.isExtensible(),非对象的第一个参数会被强制转换为一个对象。

/**
 * Reflect.ownKeys()
 * 静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
 * => keysArray
 */
//Reflect.ownKeys(target)

const obj10Prototype = {
    level: 1
};
const obj10 = Object.create(obj10Prototype, {
    name: {
        value: 'obj10'
    },
    age: {
        value: 10
    }
});
const target10 = Reflect.ownKeys(obj10);
const targetO10 = Object.getOwnPropertyNames(obj10);
// console.log(target10, targetO10, obj10);

/**
 * Reflect.preventExtensions()
 * 静态方法 Reflect.preventExtensions() 方法阻止新属性添加到对象 (例如:防止将来对对象的扩展被添加到对象中)。
 * 该方法与 Object.preventExtensions()相似,但有一些不同点。
 * 返回一个 Boolean 值表明目标对象是否成功被设置为不可扩展。
 * => boolean
 */
//Reflect.preventExtensions(target)
const obj11 = {
    name: 'obj11',
    age: 11
};
// const targetO11 = Object.preventExtensions(obj11)
// console.log(Object.isExtensible(obj11), targetO11);
const target11 = Reflect.preventExtensions(obj11);
// console.log(Object.isExtensible(obj11), Reflect.isExtensible(obj11), target11);

/**
 * Reflect.set()
 * 静态方法 Reflect.set() 工作方式就像在一个对象上设置一个属性。
 * target
 * 设置属性的目标对象。
 * propertyKey
 * 设置的属性的名称。
 * value
 * 设置的值。
 * receiver
 * 如果遇到 setter,receiver则为setter调用时的this值。
 * 返回一个 Boolean 值表明是否成功设置属性。
 * Reflect.set 方法允许你在对象上设置属性。
 * 它的作用是给属性赋值并且就像 property accessor 语法一样,但是它是以函数的方式。 
 * => boolean
 */
//Reflect.set(target, propertyKey, value[, receiver])
const obj12 = {};
const target12 = Reflect.set(obj12);
// console.log(obj12, target12, Reflect.getOwnPropertyDescriptor(obj12));

/**
 * Reflect.setPrototypeOf()
 * 除了返回类型以外,
 * 静态方法 Reflect.setPrototypeOf() 与 Object.setPrototypeOf() 方法是一样的。
 * 它可设置对象的原型(即内部的 [[Prototype]] 属性)为另一个对象或 null,
 * 如果操作成功返回 true,否则返回 false。
 * target
 * 设置原型的目标对象。
 * prototype
 * 对象的新原型(一个对象或 null)。
 * =>boolean
 */
//Reflect.setPrototypeOf(target, prototype)
const obj13 = {
    name: 'obj13',
    age: 13
};
const obj13Prototype = {
    level: 1
};
// const targetO13 = Object.setPrototypeOf(obj13, obj13Prototype);
// console.log(obj13Prototype.isPrototypeOf(obj13), targetO13);



console 命令行工具 X clear

                    
>
console