一、Reflect对象

二、Reflect API汇总

三、Reflect中的13个静态方法 

1. Reflect.get()

2. Reflect.set() 

3. Reflect.has()

4. Reflect.deleteProperty()

5. Reflect.construct()

6. Reflect.getPrototypeOf()

7. Reflect.setPrototypeOf() 

8. Reflect.defineProperty()

9. Reflect.getOwnPropertyDescriptor() 

10. Reflect.apply()

11. Reflect.isExtensible ()

12. Reflect.preventExtensions()  

13. Reflect.ownKeys () 


一、Reflect对象

Reflect,反射,JavaScript中的内置对象;反射是在程序运行中获取和动态操作自身内容的一项技术;

  • 将JavaScript中能够实现反射的方法都统一起来,方便使用;
  • 提供了13个操作对象的静态方法;静态方法(类方法),使用static关键字修饰的方法,使用【类名.方法名】进行调用;

二、Reflect API汇总

序号Reflect API含义类似于
1Reflect.get()读取对象属性obj.key 或 obj["key"]
2Reflect.set()在对象上设置属性obj.key = value 或 obj["key"] = value
3Reflect.has()判断对象是否拥有某个属性in 操作符
4Reflect.deleteProperty()删除对象的属性delete 操作符
5Reflect.construct()调用构造函数创建实例对象new 操作符
6Reflect.getPrototypeOf()返回对象的原型Object.getPrototypeOf()
7Reflect.setPrototypeOf()设置对象的原型Object.setPrototypeOf()
8

Reflect.getOwnPropertyDescriptor()

返回属性描述符

Object.getOwnPropertyDescriptor()

9Reflect.defineProperty()精确添加或修改对象的属性Object.defineProperty()
10Reflect.apply()调用目标函数的同时指定this和参数列表Function.prototype.apply()
11Reflect.isExtensible()判断一个对象是否可扩展;Object.isExtensible()
12Reflect.preventExtensions()

阻止新属性添加到对象(阻止扩展);

Object.preventExtensions()
13Reflect.ownKeys()

返回自身属性键组成的数组;

Object.getOwnOropertyNames()与

Object.getOwnPropertySymbols()之和

三、Reflect中的13个静态方法 

1. Reflect.get()

(1)语法

Reflect.get ( target,  key,  [,receiver] )

该方法用于查找或者获取对象的属性,类似于【target[key]target.key】;

该方法接收三个参数:

  • target:获取的目标对象;
  • key:目标对象的属性名;
  • receiver:可选参数;如果key使用getter绑定访问该属性时的读取函数(计算属性),则其this指向receiver对象;

该方法返回读取目标对象的属性值; 

(2)试一试

// 1. 使用Reflect.get()获取对象属性;
let obj = {
    name: "zyl",
    age: 18,
    get info() {
        return `info--> 姓名: ${this.name} ; 年龄 : ${this.age}`
    },
};

console.log(Reflect.get(obj, "name")); // zyl
console.log(Reflect.get(obj, "age")); // 18
console.log(Reflect.get(obj, "phone")); //  undefined
console.log(Reflect.get(obj, "info")); // info--> 姓名: zyl ; 年龄 : 18

// 2. 传入receiver对象
let newObj = {
    name:'ll',
    age:20
}
console.log(Reflect.get(obj, "info", newObj)); // info--> 姓名: ll ; 年龄 : 20

// 3. 传入的target不是对象
// console.log(Reflect.get(1, "name")); // Reflect.get called on non-object"
// console.log(Reflect.get(false, "name")); // Reflect.get called on non-object"
console.log(Reflect.get('str', "name")); // Reflect.get called on non-object"

(3)注意

  • 若没有key属性,则返回undefined;
  • 如果target不是Object,则会抛出TypeError异常;

2. Reflect.set() 

(1)语法

Reflect.set ( target, key, value, [,receiver] )

该方法用于给目标对象添加属性,类似于【target.key = valuetarge["key"] = value】;

该方法接收四个参数:

  • target:添加属性的目标对象;
  • key:添加的属性名;
  • value:添加的属性值;
  • receiver:可选参数,如果有setter,则receiver为setter调用时的this值;

该方法返回一个布尔值,表明属性添加是否成功; 

 (2)试一试

// 设置对象的属性
let obj = {};
let res = Reflect.set(obj, "name", "zyl");
console.log(res); // true
console.log(obj); // {name: 'zyl'}

// 改变this指向
let objNew = {};
let res1 = Reflect.set(obj, "name", "ll", objNew);
console.log(res1); // true
console.log(obj); // {name: 'zyl'}
console.log(objNew); // {name: 'll'}

// 设置数组的值
let arr = [11];
let res2 = Reflect.set(arr, 1, 22);
console.log(res2); // true
console.log(arr); // [11, 22]

// 截断数组
let res3 = Reflect.set(arr, "length", 1);
console.log(res3); // true
console.log(arr); // [11]

// 传入的target非对象
let res4 = Reflect.set('11', 'abc','123') // 报错:Reflect.set called on non-object"

(3)异常

如果target不是Object,则会抛出TypeError异常;

3. Reflect.has()

(1)语法

Reflect.has ( target, key ) 

该方法用于判断target对象中是否具有key属性, 类似于【key in target】操作;

该方法接收两个参数:

  • target:检查的目标对象;若传入的target非对象,则报错;
  • key:检查的key属性;

该方法返回一个布尔值,表示对象中是否包含该属性;

(2)试一试

// 判断target中是否存在key属性
let obj = {
  name:'zyl'
}
console.log(Reflect.has(obj, 'name'));  // true
console.log(Reflect.has(obj, 'age'));  // false
// console.log(Reflect.has(1, 'age'));  // 报错:“Reflect.has called on non-object”

// 相当于 in 操作符
console.log('name' in obj); // true
console.log('age' in obj);  // false

(3)异常

如果target不是Object,则会抛出TypeError异常;

4. Reflect.deleteProperty()

(1)语法

 Reflect.deleteProperty ( target, key )

该方法用于删除目标对象中的属性,类似于【delete target.key】操作;

该方法接收两个参数:

  • target:要删除属性的目标对象;
  • key:要删除的目标属性;

该方法返回一个布尔值,表示删除是否成功;

(2)试一试

let obj = {
  name:'zyl',
  phone:'111111111'
}
console.log(Reflect.deleteProperty(obj, 'name')); // true
console.log(Reflect.deleteProperty(obj, 'age'));  // true
console.log(obj); // {phone: '111111111'}
// console.log(Reflect.deleteProperty(true, 'age'));  // 报错:“Reflect.deleteProperty called on non-object”

// 相当于delete 操作符
console.log(delete obj.phone);  // true
console.log(obj); // {}

(3)异常

如果target不是Object,则会抛出TypeError异常; 

5. Reflect.construct()

(1)语法

Reflect.construct ( target, args [, newTarget ] )

该方法用于创建一个对象实例,类似于【new Function】实例化操作;

该方法接收三个参数:

  • target:用于创建实例对象的目标构造函数;
  • args:传递给构造函数的参数列表,以数组的形式;
  • newTarget:可选参数;指定新创建对象的构造函数;

该方法返回一份实例对象(以target为构造函数,以args为初始化参数;若newTarget存在,则以newTarget为构造函数); 

(2)试一试

function Person(name, age) {
  this.name = name;
  this.age = age;
}

let p1 = Reflect.construct(Person, ['ace', 20]);
console.log(p1);  // Person {name: 'zyl', age: 18}

// 相当于new运算符
let p2 = new Person('zyl', 18);
console.log(p2);  // Person {name: 'ace', age: 20}


// 指定新创建对象的构造函数
function newPerson(name, age){
  this.name = '姓名:' + name;
  this.age = '年龄:'+ age;
}
let p3 = Reflect.construct(Person, ['dingdong', 20], newPerson);
console.log(p3);  // newPerson {name: 'dingdong', age: 20}

(3)异常

如果 target 或者 newTarget 不是构造函数,则会抛出TypeError异常;

6. Reflect.getPrototypeOf()

(1)语法

Reflect.getPrototypeOf ( target )

该方法用于获取目标对象的原型(__proto__),类似于【Object.getPrototypeOf(target)】;

该方法接收一个参数:

  • target:要获取原型的目标对象;如果该参数不是对象,则会抛出一个异常;

该方法返回目标对象的原型;

(2)试一试

function Person(name, age) {
  this.name = name;
  this.age = age;
}
let p1 = Reflect.construct(Person, ["zyl", 18]);
console.log(Reflect.getPrototypeOf(p1) === Person.prototype); // true

// 对应Object.getPrototypeOf(obj)
console.log(Reflect.getPrototypeOf(p1) === Object.getPrototypeOf(p1)); // true

// 若target不是对象类型,Reflect.getPrototypeOf() 报错;而Object.getPrototypeOf() 会强制转换成对象,再执行;
console.log(Object.getPrototypeOf("abc")); // String {'', constructor: ƒ, anchor: ƒ, at: ƒ, big: ƒ, …}
console.log(Reflect.getPrototypeOf("abc")); // 报错:“ Reflect.getPrototypeOf called on non-object ”

(3)异常

如果target不是Object,则会抛出TypeError异常;

7. Reflect.setPrototypeOf() 

(1)语法 

Reflect.setPrototypeOf(target, newProto) 

该方法用于设置目标对象的原型(__proto__) ,对应【Object.setPrototypeOf(target, newProto)】;

该方法接收两个参数:

  • target:设置原型的目标对象;
  • newProto:对象的新原型(一个对象或null);

该方法返回一个Boolean值,表示给目标对象设置原型是否成功;

(2)试一试

function Person(name, age) {
  this.name = name;
  this.age = age;
}

function NewPerson(name, age) {
  this.name = name;
  this.age = age;
}

let p1 = Reflect.construct(Person, ["zyl", 18]);
console.log(p1);  // Person {name: 'zyl', age: 18}
console.log(Reflect.setPrototypeOf(p1, NewPerson)); // true

// console.log(Reflect.setPrototypeOf('123', NewPerson));  // "TypeError: Reflect.setPrototypeOf called on non-object"
// console.log(Reflect.setPrototypeOf(p1, '123')); // "TypeError: Object prototype may only be an Object or null: 123"
console.log(Reflect.setPrototypeOf(p1, null)); // true

(3)异常

 若目标对象target不是Object,或newProto既不是对象也不是null,则会抛出TypeError异常;

8. Reflect.defineProperty()

(1)语法

Reflect.defineProperty(target, key, attributes)

该方法用于给目标对象定义或修改属性描述符,类似于【Object.defineProperty()】;

该方法接收三个参数:

  • target:修改或添加属性的目标对象;
  • key:修改或添加的属性名;
  • attributes:要定义或修改的属性的描述;

该方法返回一个Boolean值,表示定义或修改是否成功;

(2)试一试

let obj = {};

console.log(Reflect.defineProperty(obj, "name", { value: "zyl" })); // true

console.log(
  Reflect.defineProperty(obj, "age", {
    value: 18,
    configurable: true,
    writable: true,
    enumerable: true,
  })
); // true

console.log(obj); // {age: 18, name: 'zyl'}

console.log(Reflect.defineProperty('obj', "name", { value: "zyl" })); // "TypeError: Reflect.defineProperty called on non-object"

(3)异常

 若target不是Object,则抛出异常TypeError异常;

9. Reflect.getOwnPropertyDescriptor() 

(1)语法

Reflect.getOwnPropertyDescriptor(target, key) 

该方法用于获取目标对象给定属性的属性描述符,类似于【Object.getOwnPropertyDescriptor(target, key) 

该方法接收两个参数:

  • target:获取属性描述符的目标对象;
  • key:获取属性描述符的给定属性名;

如果目标对象中包含该属性,则返回其属性描述符;否则,返回undefined;

(2)试一试

let obj = {};

Reflect.defineProperty(obj, "name", {
  value: "zyl",
  writable: true,
  enumerable: true,
  configurable: true,
});

console.log(Reflect.getOwnPropertyDescriptor(obj, "name")); //{value: 'zyl', writable: true, enumerable: true, configurable: true}
console.log(Reflect.getOwnPropertyDescriptor(obj, "age")); //undefined

(3)异常

若target不是Object,则抛出TypeError异常;

10. Reflect.apply()

(1)语法

Reflect.apply(targetFunction, thisArgument, argumentsList) 

该方法用于指定this对象后,执行目标函数,类似于【Function.prototype.apply.call(func, thisArg, args)】;

该方法接收三个参数:

  • targetFunction:要执行的目标函数;
  • thisArgument:目标函数调用时绑定的this对象;
  • argumentsList:目标函数接收的实参列表(类数组对象);

该方法返回目标函数调用后的返回结果(指定this对象和实参列表);

(2)试一试

let person = {
  name: "zl",
  age: 18,
};

function getAge(obj) {
  console.log(this);
  return `年龄是${obj.age}`;
}

let newPerson = {
  name: "ll",
  age: 20,
};

console.log(Reflect.apply(getAge, undefined, [person])); // undefined 年龄是18
console.log(Reflect.apply(getAge, newPerson, [person])); // {name: 'll', age: 20} 年龄是18

console.log(Reflect.apply(Math.floor, undefined, [1.75])); // 1
console.log(Reflect.apply("1111", undefined, [1.75])); //  "TypeError: Function.prototype.apply was called on 1111, which is a string and not a function"

(3)异常

若target函数不可调用,则抛出异常TypeError异常; 

11. Reflect.isExtensible ()

(1)语法 

Reflect.isExtensible(target)

该方法用于判断目标对象是否可扩展(是否可以添加新属性),类似于【Object.isExtensible()】;

该方法接收一个参数:

  • target:用于判断的目标对象;

该方法返回一个Boolean值,表示该是否可扩展;

(2)试一试

let obj = {};
console.log(Reflect.isExtensible(obj)); // true
obj.name = "ll";
console.log(obj); // {name: 'll'}
console.log(Reflect.preventExtensions(obj)); // true; 设置为不可扩展 
console.log(Reflect.isExtensible(obj)); // false
console.log(Reflect.isExtensible("111")); // "TypeError: Reflect.isExtensible called on non-object"

(3)注意

若target不是Object,则抛出异常TypeError异常;

12. Reflect.preventExtensions()  

(1)语法

Reflect.preventExtensible(target)

该方法用于阻止给目标对象添加属性,类似于【Object.preventExtensible(target)】;

该方法接收一个参数:

  • target:阻止添加属性的目标对象;

该方法返回Boolean值,表明目标对象是否被成功设置为不可扩展;

(2)试一试

let obj = {};
obj.name = "zyl";
console.log(obj); // {name: 'zyl'}
console.log(Reflect.preventExtensions(obj)); // true
// console.log(Reflect.preventExtensions('111')); // "TypeError: Reflect.preventExtensions called on non-object"
console.log((obj.age = 18)); //  "TypeError: Cannot add property age, object is not extensible"

(3)注意

若target不是Object,则抛出异常TypeError异常;

13. Reflect.ownKeys () 

(1)语法

Reflect.ownKeys(target)

该方法用于获取目标对象的所有属性键组成的数组,类似于【Object.getOwnPropertyNamesObject.getOwnPropertySymbols之和】;

该方法接受一个参数:

  • target:获取自身属性键数组的目标对象;

该方法返回一个数组(目标对象所有属性键组成的数组,包括符号类型) ;

(2)试一试

const s1 = Symbol();
const s2 = Symbol();
let obj = {
  name: "zyl",
  age: 18,
  [s1]: "aaa",
  [s2]: "bbb",
};
console.log(Reflect.ownKeys(obj)); //  ['name', 'age', Symbol(), Symbol()]
console.log(Object.getOwnPropertyNames(obj)); // ['name', 'age']
console.log(Object.getOwnPropertySymbols(obj)); //  [Symbol(), Symbol()]

let arr = [1, 2, 4, 5, 3];
console.log(Reflect.ownKeys(arr)); // ['0', '1', '2', '3', '4', 'length']

console.log(Reflect.ownKeys('1111')); // "TypeError: Reflect.ownKeys called on non-object"
},

(3)异常

若target不是Object,则会抛出TypeError异常;

============================================================

每天进步一点点,记录一下JavaScript中Reflect这个对象的相关内容~!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐