JavaScript
Reflect
Reflect 是什么 Reflect 将 Object 明显属于语言内部的方法放在 Reflect 对象上,比如 Object.defineProperty,可以用 Reflect.defineProperty Reflect 对返回值做了处理,Object.defineProperty 遇到无法定义的属性时,会抛出异常,而 Reflect.defineProperty 会返回 false 让 …
Reflect 是什么 Reflect 将 Object 明显属于语言内部的方法放在 Reflect 对象上,比如 Object.defineProperty,可以用 Reflect.defineProperty Reflect 对返回值做了处理,Object.defineProperty 遇到无法定义的属性时,会抛出异常,而 Reflect.defineProperty 会返回 false 让 …
var target = {};
var proxy = new Proxy(target, {
set: function(target, name, value, receiver) {
var success = Reflect.set(target, name, value, receiver);
if (success) {
console.log('property ' + name + ' on ' + JSON.stringify(target) + ' set to ' + value);
}
return success;
}
});
proxy.name = 'hello';
// 输出
// property name on {"name":"hello"} set to hello
var obj = {};
var loggedObj = new Proxy(obj, {
get(target, name) {
console.log('get', target, name);
return Reflect.get(target, name);
},
deleteProperty(target, name) {
console.log('delete' + name);
return Reflect.deleteProperty(target, name);
},
has(target, name) {
console.log('has' + name);
return Reflect.has(target, name);
}
});
console.log(loggedObj.name == 1);
'name' in loggedObj;
delete loggedObj.name;
// 输出
// get {} name
// false
// hasname
// deletename
console.log(Function.prototype.apply.call(Math.floor, undefined, [1.75]));
console.log(Reflect.apply(Math.floor, undefined, [1.75]));
// 输出
// 1
// 1
// 1、等同于Function.prototype.apply.call(func, thisArg, args),用于绑定this对象后执行给定函数
Reflect.apply(target, thisArg, args);
// 2、等同于new target(...args),提供了一种不使用new来调用构造函数的方法
Reflect.construct(target, args);
// 3、等同于查找并返回target对象的name属性
Reflect.get(target, name, receiver);
// 4、设置target对象的name属性等于value
Reflect.set(target, name, value, receiver);
// 5、等同于Object.defineProperty,用来为对象定义属性
Reflect.defineProperty(target, name, desc);
// 6、等同于delete obj[name],删除target的name属性
Reflect.deleteProperty(target, name);
// 7、等同于in运算符,target是否有name属性
Reflect.has(target, name);
// 8、等同于Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和,用于返回对象的所有属性
Reflect.ownKeys(target);
// 9、等同于Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展
Reflect.isExtensible(target);
// 10、等同于Object.preventExtensions方法,用于让一个对象变为不可扩展
Reflect.preventExtensions(target);
// 11、等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象
Reflect.getOwnPropertyDescriptor(target, name);
// 12、等同于Object.getPrototypeOf(obj),用于读取对象的__proto__属性
Reflect.getPrototypeOf(target);
// 13、等同于Object.setPrototypeOf(obj, newProto),用于设置目标对象的原型(prototype)
Reflect.setPrototypeOf(target, prototype);
等同于 Function.prototype.apply.call(func, thisArg, args),用于绑定 this 对象后执行给定函数
const ages = [11, 33, 12, 54, 18, 96];
// 旧写法
const youngest1 = Math.min.apply(Math, ages);
const oldest1 = Math.max.apply(Math, ages);
const type1 = Object.prototype.toString.call(youngest1);
// 新写法
const youngest2 = Reflect.apply(Math.min, Math, ages);
const oldest2 = Reflect.apply(Math.max, Math, ages);
const type2 = Reflect.apply(Object.prototype.toString, youngest2, []);
console.log(youngest1, oldest1, type1);
console.log(youngest2, oldest2, type2);
// 输出
// 11 96 "[object Number]"
// 11 96 "[object Number]"
等同于 new target(...args),提供了一种不使用 new 来调用构造函数的方法
function Greeting(name) {
this.name = name;
}
// new 的写法
const instance1 = new Greeting('张三');
// Reflect.construct 的写法
const instance2 = Reflect.construct(Greeting, ['张三']);
console.log(instance1);
console.log(instance2);
// 输出
// Greeting {name: "张三"}
// Greeting {name: "张三"}
等同于查找并返回 target 对象的 name 属性
var myObject = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar;
}
};
var reflectResult1 = Reflect.get(myObject, 'foo');
var reflectResult2 = Reflect.get(myObject, 'bar');
var reflectResult3 = Reflect.get(myObject, 'baz');
console.log(reflectResult1);
console.log(reflectResult2);
console.log(reflectResult3);
// 输出
// 1
// 2
// 3
// 如果name属性部署了读取函数getter,则读取函数this绑定的receiver
var myObject = {
foo: 1,
bar: 2,
get baz() {
return this.foo + this.bar;
}
};
var myReceiverObject = {
foo: 4,
bar: 4
};
var reflectResult4 = Reflect.get(myObject, 'baz', myReceiverObject);
console.log(reflectResult4);
// 输出
// 8
设置 target 对象的 name 属性等于 value
var myObject = {
foo: 1,
set bar(value) {
return (this.foo = value);
}
};
var reflectResult5 = myObject.foo;
Reflect.set(myObject, 'foo', 2);
var reflectResult6 = myObject.foo;
Reflect.set(myObject, 'bar', 3);
var reflectResult7 = myObject.foo;
console.log(reflectResult5);
console.log(reflectResult6);
console.log(reflectResult7);
// 输出
// 1
// 2
// 3
ar myObject = {
foo: 4,
set bar(value) {
return this.foo = value;
},
};
var myReceiverObject = {
foo: 0,
};
Reflect.set(myObject, 'bar', 2, myReceiverObject);
var reflectResult8 = myObject.foo
var reflectResult9 = myReceiverObject.foo
console.log(reflectResult8)
console.log(reflectResult9)
// 输出
// 4
// 2
// Proxy拦截属性的赋值,Reflect完成完成赋值的默认行为,传入了receiver,那么Relect会触发Proxy.defineProperty拦截
let p = {
a: 'a'
};
let handler = {
set(target, key, value, receiver) {
console.log('set');
Reflect.set(target, key, value, receiver);
},
defineProperty(target, key, attribute) {
console.log('defineProperty');
Reflect.defineProperty(target, key, attribute);
}
};
let obj2 = new Proxy(p, handler);
obj2.a = 'A';
// 输出
// set
// defineProperty
// Proxy.set的receiver总是指向当前Proxy实例,Reflect.set一旦传入receiver,就会将属性赋值到receiver,就是obj2上,导致触发defineProperty,如果Refelct.set没有传入receiver,就不会触发defineProperty拦截
let p2 = {
a: 'a'
};
let handler2 = {
set(target, key, value, receiver) {
console.log('set');
// Reflect.set(target, key, value)
},
defineProperty(target, key, attribute) {
console.log('defineProperty');
Reflect.defineProperty(target, key, attribute);
}
};
let obj3 = new Proxy(p, handler2);
obj3.a = 'A';
// 输出
// set
等同于 Object.defineProperty,用来为对象定义属性
function MyDate() {}
// 旧写法
Object.defineProperty(MyDate, 'now', {
value: () => Date.now()
});
// 新写法
var reflectResult18 = Reflect.defineProperty(MyDate, 'now', {
value: () => Date.now()
});
console.log(MyDate.now());
console.log(MyDate.now());
// 输出
// 1555681656908
// 1555681656908
// Proxy对属性进行拦截,使用Reflect.defineProperty完成了赋值
const p4 = new Proxy(
{},
{
defineProperty(target, prop, descriptor) {
console.log(descriptor);
return Reflect.defineProperty(target, prop, descriptor);
}
}
);
var reflectResult17 = (p4.foo = 'bar');
var reflectResult18 = p4.foo;
console.log(reflectResult17);
console.log(reflectResult18);
// 输出
// {value: "bar", writable: true, enumerable: true, configurable: true}
// bar
// bar
等同于 delete obj[name],删除 target 的 name 属性
const myObj2 = {
foo: 'bar'
};
// 旧写法
delete myObj2.foo;
// 新写法
Reflect.deleteProperty(myObj2, 'foo');
console.log(myObj2);
// 输出
// {}
等同于 in 运算符,target 是否有 name 属性
var myObject = {
foo: 1
};
// 旧写法
var reflectResult10 = 'foo' in myObject;
// 新写法
var reflectResult11 = Reflect.has(myObject, 'foo');
console.log(reflectResult10);
console.log(reflectResult11);
// 输出
// true
// true
等同于 Object.getOwnPropertyNames 与 Object.getOwnPropertySymbols 之和,用于返回对象的所有属性
var myObject = {
foo: 1,
bar: 2,
[Symbol.for('baz')]: 3,
[Symbol.for('bing')]: 4
};
// 旧写法
var reflectResult24 = Object.getOwnPropertyNames(myObject);
var reflectResult25 = Object.getOwnPropertySymbols(myObject);
// 新写法
var reflectResult26 = Reflect.ownKeys(myObject);
console.log(reflectResult24);
console.log(reflectResult25);
console.log(reflectResult26);
// 输出
// ["foo", "bar"]
// [Symbol(baz), Symbol(bing)]
// ["foo", "bar", Symbol(baz), Symbol(bing)]
等同于 Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展
const myObject5 = {};
// 旧写法
var reflectResult19 = Object.isExtensible(myObject5);
// 新写法
var reflectResult20 = Reflect.isExtensible(myObject5);
console.log(reflectResult19);
console.log(reflectResult20);
// 输出
// true
// true
等同于 Object.preventExtensions 方法,用于让一个对象变为不可扩展
var myObject6 = {
a: 'a',
b: ['b']
};
// 旧写法
var reflectResult21 = Object.preventExtensions(myObject6);
// 新写法
var reflectResult22 = Reflect.preventExtensions(myObject6);
var reflectResult23 = Reflect.isExtensible(myObject6);
console.log(reflectResult21);
console.log(reflectResult22);
console.log(reflectResult23);
// 输出
// {}
// true
// false
等同于 Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象
var myObject = {};
Object.defineProperty(myObject, 'hidden', {
value: true,
enumerable: false
});
// 旧写法
var theDescriptor1 = Object.getOwnPropertyDescriptor(myObject, 'hidden');
// 新写法
var theDescriptor2 = Reflect.getOwnPropertyDescriptor(myObject, 'hidden');
console.log(theDescriptor1);
console.log(theDescriptor2);
// 输出
// {value: true, writable: false, enumerable: false, configurable: false}
// {value: true, writable: false, enumerable: false, configurable: false}
等同于 Object.getPrototypeOf(obj),用于读取对象的proto属性
function Test() {}
const myObj = new Test();
// 旧写法
var reflectResult12 = Object.getPrototypeOf(myObj) === Test.prototype;
// 新写法
var reflectResult13 = Reflect.getPrototypeOf(myObj) === Test.prototype;
console.log(reflectResult12);
console.log(reflectResult13);
// 输出
// true
// true
等同于 Object.setPrototypeOf(obj, newProto),用于设置目标对象的原型(prototype)
const myObj3 = {};
// 旧写法
var reflectResult14 = Object.setPrototypeOf(myObj3, Array.prototype);
// 新写法
var reflectResult15 = Reflect.setPrototypeOf(myObj3, Array.prototype);
var reflectResult16 = myObj3.length;
console.log(reflectResult14);
console.log(reflectResult15);
console.log(reflectResult16);
// 输出
// Array {}
// true
// 0
// 建一个Set集合
const queuedObservers = new Set();
// 将所有watcher(观察者) add到队列中去
const observer = (fn) => queuedObservers.add(fn);
// 建立一个监听对象的赋值操作模型,一旦有赋值操作,就执行观察着的print方法
const observable = (obj) => new Proxy(obj, { set });
function set(target, key, value, receiver) {
const result = Reflect.set(target, key, value, receiver);
queuedObservers.forEach((observer) => observer());
return result;
}
// 依赖收集
const person = observable({
name: '张三',
age: 23
});
// 打印方法
function print() {
console.log(`${person.name}, ${person.age}`);
}
// 派发过程
observer(print);
person.name = 'hello,我的年龄是';
// 输出
// hello,我的年龄是, 23
暂无评论
确认操作
请再次确认编辑图片
待上传图片 (剩余 0 张)
项目详情
确认评论邮箱
邀请制评论