zl程序教程

您现在的位置是:首页 >  前端

当前栏目

【笔记】再学JavaScript ES(6-10)全版本语法——反射机制及应用

2023-09-27 14:26:51 时间


Reflect

1.案例:四舍五入

{
  let price = 91.5
  // ES5
  console.log(
    price = price > 100
      ? Math.floor.apply(null, [price])
      : Math.ceil.apply(null, [price])
  )
  // ES6
  console.log(
    Reflect.apply(
      price > 100 ? Math.floor : Math.ceil, null, [price]
    )
  )
}

2.案例:获得时间戳

{
  // ES5
  let d1 = new Date()
  console.log(
    d1.getTime(),
    d1 instanceof Date // true
  )
  // ES6
  let d2 = Reflect.construct(Date, []) // 注意:这里必须要传入一个空数组作为参数列表
  console.log(
    d2.getTime(),
    d2 instanceof Date // true
  )
}

3.案例:对象操作

(1)对象增加属性

// ES5: 对象增加属性
const obj1 = {}
const o1 = Object.defineProperties(obj1, {
  'A': { value: 'a', writable: true },
  'B': { value: 'b' },
  'C': { value: 'c', configurable: true },
  'D': { value: 'd', configurable: true }
})
console.log(
  obj1, // {A: "a", B: "b", C: "c", D: "d"}
  o1 // {A: "a", B: "b", C: "c", D: "d"}
)
// ES6: 对象增加属性
const obj2 = {}
const o2 = [
  Reflect.defineProperty(obj2, 'A', { value: 'a', writable: true }),
  Reflect.defineProperty(obj2, 'B', { value: 'b' }),
  Reflect.defineProperty(obj2, 'C', { value: 'c', configurable: true })
]
console.log(
  obj2, // {A: "a", B: "b", C: "c"}
  o2 // [true, true, true]
)

(2)对象删除属性

// ES5: 对象删除属性
console.log(delete obj1.C) // true
console.log(obj1) // {A: "a", B: "b", D: "d"}
console.log(delete obj1['D']) // false
console.log(obj1) // {A: "a", B: "b"}
// ES6: 对象删除属性
console.log(Reflect.deleteProperty(obj2, 'C')) // false
console.log(obj2) // {A: "a", B: "b"}

(3)对象读写属性

// ES5: 对象读写属性
console.log(obj1.A = 'aa') // aa
console.log(obj1.A) // aa
// ES6: 对象读写属性
console.log(Reflect.set(obj2, 'A', 'aa')) // true
console.log(Reflect.get(obj2, 'A')) // aa

(4)获取对象属性描述

// ES5: 获取对象属性描述
console.log(Object.getOwnPropertyDescriptor(obj1, 'A')) // {value: "a", writable: false, enumerable: false, configurable: false}
// ES6: 获取对象属性描述
console.log(Reflect.getOwnPropertyDescriptor(obj2, 'A')) // {value: "a", writable: false, enumerable: false, configurable: false}
  • value:该属性的值(仅针对数据属性描述符有效)
  • writable:当且仅当属性的值可以被改变时为true。(仅针对数据属性描述有效)
  • get:获取该属性的访问器函数(getter)。如果没有访问器, 该值为undefined。(仅针对包含访问器或设置器的属性描述有效)
  • set:获取该属性的设置器函数(setter)。 如果没有设置器, 该值为undefined。(仅针对包含访问器或设置器的属性描述有效)
  • configurable:当且仅当指定对象的属性描述可以被改变或者属性可被删除时,为true。
  • enumerable:当且仅当指定对象的属性可以被枚举出时,为 true。

(5)读写对象原型链上的方法

// ES5: 读写对象原型链上的方法
console.log(Object.setPrototypeOf(obj1, String.prototype)) // String {A: "aa", B: "b"}
console.log(Object.getPrototypeOf(obj1)) // String {"", constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ…}
// ES6: 读写对象原型链上的方法
console.log(Reflect.setPrototypeOf(obj2, String.prototype)) // true
console.log(Reflect.getPrototypeOf(obj2)) // String {"", constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ…}

(6)判断对象是否有某个属性

// ES5: 判断对象是否有某个属性
console.log(obj1.E) // undefined
// ES6: 判断对象是否有某个属性
console.log(Reflect.has(obj2, 'E')) // false

(7)判断对象是否可拓展(冻结、密封)

// ES5: 判断对象是否可拓展
console.log(Object.isExtensible(obj1)) // true
// 阻止拓展
Object.preventExtensions(obj1)
console.log(Object.isExtensible(obj1)) // false
// 冻结
Object.freeze(obj1)
console.log(Object.isFrozen(obj1)) // true
// 密封
Object.seal(obj1)
console.log(Object.isSealed(obj1)) // true
// ES6: 判断对象是否可拓展
console.log(Reflect.isExtensible(obj2)) // true
// 阻止拓展
console.log(Reflect.preventExtensions(obj2)) // true
console.log(Reflect.isExtensible(obj2)) // false

阻止对象扩展后:

  • 不能添加属性。
  • 可以修改属性的值。
  • 可以删除属性。
  • 可以修改属性描述符。
    在这里插入图片描述

拓展:

拓展: