文章目錄
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
阻止對象擴展後:
- 不能添加屬性。
- 可以修改屬性的值。
- 可以刪除屬性。
- 可以修改屬性描述符。
拓展:
拓展: