一、Reflect是什么
Reflect是ES6提供的一个内置对象,Reflect的所有属性/方法都是静态的,共有13个静态方法,使用起来和Math一样
console.log(Reflect) // Reflect {defineProperty: ƒ, deleteProperty: ƒ, apply: ƒ, construct: ƒ, get: ƒ, …}
console.log(Object.prototype.toString.call(Reflect)) // [object Reflect]
二、Reflect.apply()
1、语法
Reflect.apply(target, thisArgument, argumentList)
2、可以替代函数原型上的apply方法,但是使用时有些区别:
const obj = {
age: 18
}
function fn(a, b, c) {
return this.age + a + b + c
}
console.log(fn.apply(obj, [1, 2, 3])) // 24 老写法
console.log(Reflect.apply(fn, obj, [1, 2, 3])) // 24 新写法
三、Reflect.construct
1、语法
Reflect.construct(target, argumentList)
2、可以替代new target(...args),使用时有些区别:
function Person(name, age) {
this.name = name
this.age = age
}
const p1 = new Person('张三', 18)
const p2 = Reflect.construct(Person, ['张三', 18])
console.log(p1) // Person {name: '张三', age: 18}
console.log(p2) // Person {name: '张三', age: 18}
四、Reflect.get
1、语法
- target:必传,且必须是一个对象
- propertyKey:对象属性名
- receiver:Reflect.get的真正用途,在调用对象中的getter方法时,改变其中this的指向
Reflect.get(target, propertyKey, receiver)
2、只传前2个参数时,和obj.语法获取属性值没有区别
const obj = {
name: '张三',
age: 18,
get info() {
return `${this.name},${this.age}`
},
undefined: 1
}
console.log(obj.name) // 张三
console.log(obj.age) // 18
console.log(obj.info) // 张三,18
console.log(obj.a) // undefined
console.log(Reflect.get(obj, 'name')) // 张三
console.log(Reflect.get(obj, 'age')) // 18
console.log(Reflect.get(obj, 'info')) // 张三,18
console.log(Reflect.get(obj, 'a')) // undefined
console.log(Reflect.get(obj)) // 1 第二个参数是undefined
3、传入receiver参数
console.log(Reflect.get(obj, 'info')) // 张三,18
const xiaoming = {
name: '小明',
age: 10
}
console.log(Reflect.get(obj, 'info', xiaoming)) // 小明,10 obj中getter方法中的this被指向到xiaoming
五、Reflect.set
1、语法
- target:必传,且必须是一个对象
- propertyKey:对象属性名
- value:对象属性值
- receiver:Reflect.set的真正用途,在调用对象中的setter方法时,改变其中this的指向
Reflect.set(target, propertyKey, value, receiver)
2、只传前3个参数,和使用obj.xx = 'xxx'赋值属性没有区别
const obj = {
name: '张三',
age: 18,
set setInfo({ name, age }) {
this.name = name
this.age = age
}
}
console.log(obj) // {name: '张三', age: 18}
Reflect.set(obj, 'setInfo', { name: 'xxx', age: 10 })
console.log(obj) // {name: 'xxx', age: 10}
3、传入receiver参数
当传递了receiver时,setter中的this便指向receiver,所以是xiaoming这个对象借用了obj中的setInfo方法,改变了xiaoming自己,对obj没有影响
const xiaoming = {
name: '小明'
}
Reflect.set(obj, 'setInfo', { name: '大明', age: 10 }, xiaoming)
console.log(obj) // {name: '张三', age: 18}
console.log(xiaoming) // {name: '大明', age: 10}
六、Reflect.defineProperty()
Object.defineProperty返回修改后的对象,Reflect.defineProperty返回布尔值
Object.defineProperty定义失败拦截:
try {
Object.defineProperty(obj, 'age', { value: 19 })
} catch (e) {
}
Reflect.defineProperty可以使用if语句:
if (Reflect.defineProperty(obj, 'age', { value: 19 })) {
} else {
}
七、Reflect.getOwnPropertyDescriptor()
八、Reflect.getPrototypeOf()
九、Reflect.setPrototypeOf()
十、Reflect.isExtensible()
十一、Reflect.preventExtensions()
十二、Reflect.ownKeys()
Reflect.ownKeys = Object.getOwnPropertyNames + Object.getOwnPropertySymbols
const s = Symbol()
const obj = {
name: '小明',
0: 0,
'-1': -1,
[s]: Symbol(),
100: 100,
50: 50
}
obj.__proto__.a = 'a'
Object.defineProperty(obj, 'age', { value: 18 })
const arr1 = Object.getOwnPropertyNames(obj)
const arr2 = Object.getOwnPropertySymbols(obj)
const arr3 = Reflect.ownKeys(obj)
console.log(arr1) // ['0', '50', '100', 'name', '-1', 'age']
console.log(arr2) // [Symbol()]
console.log(arr3) // ['0', '50', '100', 'name', '-1', 'age', Symbol()]
参考:Object.getOwnPropertyNames()
十三、Reflect.has()
1、语法
Reflect.has(target, propertyKey) // target必须是一个对象
2、作用和in操作符一样
const person = {
name: '小明'
}
person.__proto__.a = 'a'
console.log('name' in person) // true
console.log('toString' in person) // true
console.log('a' in person) // true
console.log(Reflect.has(person, 'name')) // true
console.log(Reflect.has(person, 'toString')) // true
console.log(Reflect.has(person, 'a')) // true
十四、Reflect.deleteProperty()
1、语法
Reflect.deleteProperty(target, propertyKey)
2、作用和delete操作符一样
const obj = {
name: '张三',
age: 18
}
Reflect.defineProperty(obj, 'gender', {
value: '男'
})
console.log(obj) // {name: '张三', age: 18, gender: '男'}
console.log(delete obj.name) // true
console.log(obj) // {age: 18, gender: '男'}
console.log(delete obj['age']) // true
console.log(obj) // {gender: '男'}
console.log(delete obj['gender']) // false 删除不可删除属性时返回false
console.log(obj) // {gender: '男'}
将delete替换为新语法,结果一样:
console.log(obj) // {name: '张三', age: 18, gender: '男'}
console.log(Reflect.deleteProperty(obj, 'name')) // true
console.log(obj) // {age: 18, gender: '男'}
console.log(Reflect.deleteProperty(obj, 'age')) // true
console.log(obj) // {gender: '男'}
console.log(Reflect.deleteProperty(obj, 'gender')) // false 删除不可删除属性时返回false
console.log(obj) // {gender: '男'}