灏天阁

Reflect 对象

· Yin灏

Reflect 对象介绍

let candy_amount = {
  duration: 30,
  strawberry: 55,
  cranberry: 10,
  blueberry: 13,
  cherry: 60,
  orange: 10,
  lemon: 10
};

Object.defineProperty(candy_amount, 'apple', {
  value: 17,
  writable: true,
  enumerable: true,
  configurable: true
})

candy_amount.watermelon = 33;

console.log(candy_amount);

let symbol01 = Symbol('mixed');

candy_amount[symbol01] = 5;

console.log(candy_amount);

// 获取对象的键值,组成一个新数组
console.log(Reflect.ownKeys(candy_amount)); // ["duration", "strawberry", "cranberry", "blueberry", "cherry", "orange", "lemon", "apple", "watermelon", Symbol(mixed)]

console.log('');

console.log(candy_amount.orange); // 10

console.log(candy_amount.watermelon); // 33

console.log(candy_amount.mixed); // undefined

console.log(candy_amount['mixed']); // undefined

console.log('');

console.log(candy_amount[symbol01]); // 5

间接应用特定函数

通过函数 Reflect.apply() 可传入多个数据,至即将被间接应用的其他函数。

let code_list = [108, 111, 118, 101, 32, 121, 111, 117];

result = String.fromCharCode(...code_list); // 返回数码所对应字符

console.log(result); // love you

result = Reflect.apply(String.fromCharCode, undefined, code_list);
console.log(result); // love you


let pointer = null;
let range_list = [10, 10, 10, 50, 50, 100, 100, 100];

function generate(...list) {
  let number_list = [];
  console.log(this.valueOf());
  for(let i = 0; i < list.length; i++) {
    number_list.push(parseInt(list[i] * Math.random()));
  }
  return number_list;
}

result = Reflect.apply(generate, 'test message', range_list);
// result = Reflect.apply(generate, undefined, range_list);

console.log(result); // [ 3, 1, 6, 6, 18, 79, 26, 77 ]

Reflect.apply 通过指定的参数列表发起对目标(target)函数的调用。

Reflect.apply(target, thisArgument, argumentsList)

/*
  target目标函数。
  thisArgumenttarget函数调用时绑定的this对象。
  argumentsListtarget函数调用时传入的实参列表,该参数应该是一个类数组的对象。
*/

创建特定对象实例

通过函数 Reflect.construct() 可以传入多个数据,至即将被间接调用的其他对象的构造函数里,进而创建特定对象的新实例。

/**
 * 通过函数 Reflect.construct() 可以传入多个数据,至即将被间接调用的其他对象的构造函数里,进而创建特定对象的新实例。
 */

let a01 = new Array(7);
console.log(a01); // [empty × 7]

let a02 = Reflect.construct(Array, [7]);
console.log(a02); // [empty × 7]

let d01 = new Date();
let d02 = Reflect.construct(Date, []);

console.log(d01); // Mon Jul 05 2021 10:23:00 GMT+0800 (中国标准时间)
console.log(d02); // Mon Jul 05 2021 10:23:00 GMT+0800 (中国标准时间)

let n01 = new Number(2591.8);
let n02 = Reflect.construct(Number, [2591.8]);

console.log(n01); // Number {2591.8}
console.log(n02); // Number {2591.8}

精细定义新属性

通过函数 Reflect.defineProperty() 可以间接对特定对象的实例,精细定义其属性及其特征。

let obj01 = {}, obj02 = {};

let result01 = null, result02 = null;

result01 = Object.defineProperty(obj01, 'name', {
  value: 'Alex',
  writable: true,
  enumerable: true,
  configurable: true
});
// 返回布尔值 true
result02 = Reflect.defineProperty(obj02, 'name', {
  value: 'Alex',
  writable: true,
  enumerable: true,
  configurable: true
});

console.log(obj01); // {name: "Alex"}
console.log(obj02); // {name: "Alex"}

console.log(result01); // {name: "Alex"}
console.log(result02); // true

删除特定属性

通过函数 Reflect.deleteProperty() 可以间接删除特定对象实例的特定属性

let inventory = {
  apple: 10,
  banana: 18,
  durian: 8,
  grapefruit: 30
};

let result = null;

result = delete inventory.apple;

console.log(result); // true
console.log(inventory); // {banana: 18, durian: 8, grapefruit: 30}

result = Reflect.deleteProperty(inventory, 'grapefruit');

console.log(result); // true
console.log(inventory); // {banana: 18, durian: 8}

获取特定属性的数据

通过函数 Reflect.get() 可以间获取特定对象实例中的特定属性数据

let inventory = { apple: 10, banana: 18, durian: 8, grapefruit: 30 };

let result = inventory.banana;

console.log(result); // 18

result = Reflect.get(inventory, 'grapefruit');
console.log(result); // 30

返回特定属性的描述器

通过函数 Reflect.getOwnPropertyDescriptor() 可间接返回特定对象实例的特定属性的描述器

let profile = {
  firstname: 'Jason',
  lastname: 'Alex',
  gender: 'male',
  age: 28,
  position: 'Product Manager',
  fullname01 () {
    return this.firstname + ' ' + this.lastname;
  },
  // 通过 get 将此函数设置为 getter,getter 被访问的时候,必须省略其小括号(profile.fullname02)
  get fullname02 () {
    return this.firstname + ' ' + this.lastname;
  }
}

let d01 = Object.getOwnPropertyDescriptor(profile, 'position');
let d02 = Object.getOwnPropertyDescriptor(profile, 'fullname01');
let d03 = Object.getOwnPropertyDescriptor(profile, 'fullname02');

console.log(d01); // {value: "Product Manager", writable: true, enumerable: true, configurable: true}
console.log(d02); // {writable: true, enumerable: true, configurable: true, value: ƒ}
console.log(d03); // {set: undefined, enumerable: true, configurable: true, get: ƒ}

console.log(profile.fullname01()); // Jason Alex
console.log(profile.fullname02); // Jason Alex

d01 = Reflect.getOwnPropertyDescriptor(profile, 'position');
d02 = Reflect.getOwnPropertyDescriptor(profile, 'fullname01');
d03 = Reflect.getOwnPropertyDescriptor(profile, 'fullname02');

console.log(d01); // {value: "Product Manager", writable: true, enumerable: true, configurable: true}
console.log(d02); // {writable: true, enumerable: true, configurable: true, value: ƒ}
console.log(d03); // {set: undefined, enumerable: true, configurable: true, get: ƒ}

// getOwnPropertyDescriptors 添加了 s
let d04 = Object.getOwnPropertyDescriptors(profile);
console.log(d04); 

/*

age: {value: 28, writable: true, enumerable: true, configurable: true}
firstname: {value: "Jason", writable: true, enumerable: true, configurable: true}
fullname01: {writable: true, enumerable: true, configurable: true, value: ƒ}
fullname02: {set: undefined, enumerable: true, configurable: true, get: ƒ}
gender: {value: "male", writable: true, enumerable: true, configurable: true}
lastname: {value: "Alex", writable: true, enumerable: true, configurable: true}
position: {value: "Product Manager", writable: true, enumerable: true, configurable: true}

*/

返回特定对象原型

通过函数 Reflect.getPrototypeOf() 可返回特定对象的原型。

let profile = {
    firstname: 'Jason',
    lastname: 'Alex',
    gender: 'male',
    age: 28,
    position: 'Product Manager',
    fullname01() {
        return this.firstname + ' ' + this.lastname;
    },
    get fullname02() {
        return this.firstname + ' ' + this.lastname;
    }
}

let result01 = Object.getPrototypeOf(profile);
let result02 = Reflect.getPrototypeOf(profile);

console.log(result01);
console.log(result02);

console.log(result01 === result02); // true

判断特定属性的存在性

通过函数 Reflect.has() 可以判断特定对象实例,是否存在特定名称的成员(属性/函数/getter/setter)


let profile = {
  firstname: 'Jason',
  lastname: 'Alex',
  gender: 'male',
  age: 28,
  position: 'Product Manager',
  fullname01 () {
    return this.firstname + " " + this.lastname;
  },
  get fullname02() {
    return this.firstname + " " + this.lastname;
  }
}


let result = Reflect.has(profile, 'age');
console.log(result); // true

result = Reflect.has(profile, 'fullname02');
console.log(result); // true

result = Reflect.has(profile, 'fullname03');
console.log(result); // false

判断与设置特定对象的扩展性

  • 通过函数 Reflect.isExtensible() 可判断特定对象实例,是否可被扩展新的属性;
  • 通过函数 Reflect.preventExtensions() 可制止特定对象实例被扩展新的属性
let profile = {
  firstname: 'Jason',
  lastname: 'Alex',
  gender: 'male',
  age: 28,
  position: 'Product Manager',
  fullname01 () {
    return this.firstname + " " + this.lastname;
  },
  get fullname02() {
    return this.firstname + " " + this.lastname;
  }
}

let result = Reflect.isExtensible(profile);
console.log(result); // true

Reflect.preventExtensions(profile);

result = Reflect.isExtensible(profile);
console.log(result); // false

profile.department = 'Product';
console.log(profile); // 不存在 department 属性

简易定义新属性

通过函数 Reflect.set() 可间接在特定对象实例中,简易定义其新属性。

let shapes = {};

shapes['diamond'] = 4;
shapes.parallelogram = 4;

Reflect.defineProperty(shapes, 'trapezoid', {
  value: 4,
  writable: false,
  enumerable: true,
  configurable: false
})

Reflect.set(shapes, 'square', 4);
Reflect.set(shapes, 'triangle', 3);

console.log(shapes); // {diamond: 4, parallelogram: 4, trapezoid: 4, square: 4, triangle: 3}

let metals = ['Zinc'];
metals.push('Silver');
metals.unshift('Gold');
metals[3] = 'Copper';

Reflect.set(metals, 4, 'Aluminum');
console.log(metals); // ["Gold", "Zinc", "Silver", "Copper", "Aluminum"]

Reflect.set(metals,'length', 10);
console.log(metals); // ["Gold", "Zinc", "Silver", "Copper", "Aluminum", empty × 5]

延申:

let array = [];
array.length = 10;
console.log(array);
array.fill(10);
console.log(array);

重新设置特定对象的原型

通过函数 Reflect.setPrototypeOf() 可重新将特定对象的原型实例,设置为另一个对象实例。

let book01 = {
  title: 'New Thoughts',
  price: 150,
  author: 'Brat Terminator',
  Publisher: 'TsingHua',
  date: '2018/06/06'
}

let book02 = {
  title: 'New Thinkings',
  price: 180,
  author: 'Brat Terminator',
  Publisher: 'TsingHua',
  date: '2018/07/07',
  version: 3
}

// 改变了原型,就会重新设置了原型属性和方法
let result = Object.setPrototypeOf(book01, String);

console.log(result);
console.log(book01);
console.log('');

result = Reflect.setPrototypeOf(book02, Number); // true
console.log(result);
console.log(book02);
// book02 的原型已被置换成为 Number 对象的原型,所以变量 book02 就被内置了常量属性 EPSILON
console.log(book02.EPSILON); // 2.220446049250313e-16

返回与列举特定对象的自定义属性

通过函数 Reflect.ownKeys() 可返回特定对象实例的自定义属性所构成的数组实例,进而搭配循环语句,以列举出特定对象实例的自定义属性

let profile = {
  firstname: 'Jason',
  lastname: 'Alex',
  gender: 'male',
  age: 28,
  position: 'Product Manager',
  fullname01() {
    return this.firstname + " " + this.lastname;
  },
  get fullname02 () {
    return this.firstname + " " + this.lastname;
  }
}

let result = Object.keys(profile);
console.log(result); // ["firstname", "lastname", "gender", "age", "position", "fullname01", "fullname02"]

result = Reflect.ownKeys(profile);
console.log(result); // ["firstname", "lastname", "gender", "age", "position", "fullname01", "fullname02"]
/**
 * 通过函数 Reflect.ownKeys() 可返回特定对象实例的自定义属性所构成的数组实例,进而搭配循环语句,以列举出特定对象实例的自定义属性
 */

let book01 = {
  title: 'New Thoughts',
  price: 150,
  author: 'Brat Terminator',
  Publisher: 'TsingHua',
  date: '2018/06/06'
}

let book02 = {
  title: 'New Thinkings',
  price: 180,
  author: 'Brat Terminator',
  Publisher: 'TsingHua',
  date: '2018/07/07',
  version: 3
}

console.log(Object.keys(book01)); //  ["title", "price", "author", "Publisher", "date"]
console.log(Reflect.ownKeys(book02)); //  ["title", "price", "author", "Publisher", "date", "version"]

let p = '';
for(p of Object.keys(book01)) {
  console.log(`The value of property'${p}'= ${book01[p]}`);
}

/*
The value of property'title'= New Thoughts
The value of property'price'= 150
The value of property'author'= Brat Terminator
The value of property'Publisher'= TsingHua
The value of property'date'= 2018/06/06
*/

console.log('\n\n');

for(p of Reflect.ownKeys(book02)) {
  console.log(`The value of property'${p}'= ${book02[p]}`);
}

/*
The value of property'title'= New Thinkings
The value of property'price'= 180
The value of property'author'= Brat Terminator
The value of property'Publisher'= TsingHua
The value of property'date'= 2018/07/07
The value of property'version'= 3
*/

- Book Lists -