● 阉割版的Map、Set
● 不能遍历(无遍历方法)
● 成员必需是对象,否则报错
● JS垃圾回收机制不会计数WeakMap跟WeakSet数据类型的引用,不考虑他的引用,是一个弱引用,不需要进入垃圾回收机制即不需要释放内存,所以不可以迭代,他是不可预测的
● 不建议使用,因为他是不稳定的
● 有很少的特殊的场景,需要使用他
是一个代理模式的实现
● let proxy = new Proxy(target, options)
let star = {
name: 'gaoyuanyuan',
age: 24,
phone: 'gaoyuanyuan188********'
};
let agent = new Proxy(star, {
// 读取操作
get: function(target, key) {
if(key === 'phone') {
return 'agent: 15566655533';
}
if(key === 'price') {
return '12k';
}
return target[key];
}
});
console.log(agent.phone); // agent: 15566655533
console.log(agent.price); // 12k
console.log(agent.name); // gaoyuanyuan
let star = {
name: 'gaoyuanyuan',
age: 24,
phone: 'gaoyuanyuan188********'
};
let agent = new Proxy(star, {
// 读取操作
get: function(target, key) {
if(key === 'phone') {
return 'agent: 15566655533';
}
if(key === 'price') {
return '12k';
}
return target[key];
},
set: function(target, key, value) {
if(value < 10000) {
throw new Error('价格太低');
}else {
target[key] = value;
return true;
}
},
});
// agent.coustomPrice = 9000; // index.html:200 Uncaught Error: 价格太低
agent.coustomPrice = 13000;
console.log(star);
● in操作符会触发has拦截操作
● for in循环不会触发has拦截操作
let star = {
name: 'gaoyuanyuan',
age: 24,
phone: 'gaoyuanyuan188********'
};
let agent = new Proxy(star, {
// 读取操作
get: function(target, key) {
if(key === 'phone') {
return 'agent: 15566655533';
}
if(key === 'price') {
return '12k';
}
return target[key];
},
set: function(target, key, value) {
if(value < 10000) {
throw new Error('价格太低');
}else {
target[key] = value;
return true;
}
},
has: function(target, key) {
console.log('请联系agent:', 15566655533);
if(key === 'coustomPrice') {
return target[key];
}else {
return false;
}
}
});
// agent.coustomPrice = 9000; // index.html:200 Uncaught Error: 价格太低
agent.coustomPrice = 13000;
console.log(star);
console.log('coustomPrice' in agent);
// 请联系agent: 15566655533
// true
for(let key in agent) {
console.log(agent[key]); // 不会触发has拦截操作
}
let star = {
name: 'gaoyuanyuan',
age: 24,
phone: 'gaoyuanyuan188********'
};
let agent = new Proxy(star, {
// 读取操作
get: function(target, key) {
if(key === 'phone') {
return 'agent: 15566655533';
}
if(key === 'price') {
return '12k';
}
return target[key];
},
set: function(target, key, value) {
if(value < 10000) {
throw new Error('价格太低');
}else {
target[key] = value;
return true;
}
},
has: function(target, key) {
console.log('请联系agent:', 15566655533);
if(key === 'coustomPrice') {
return target[key];
}else {
return false;
}
},
// 拦截删除属性的操作
deleteProperty: function(target, key) {
if(key.indexOf('_') === 0) {
delete target[key];
}
},
// 拦截 Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy) 、Object.keys(proxy),返回一个数组。该方法返回目标对象所有自身的属性的属性名,而 Object.keys() 的返回结果仅包括目标对象自身的可遍历属性。
ownKeys: function(target) {
}
});
// agent.coustomPrice = 9000; // index.html:200 Uncaught Error: 价格太低
agent.coustomPrice = 13000;
console.log(star);
console.log('coustomPrice' in agent);
// 请联系agent: 15566655533
// true
for(let key in agent) {
console.log(agent[key]); // 不会触发has拦截操作
}
agent._foo = {
a: 1
}
console.log(delete agent._foo);
console.log(agent);
以前通过操作符调用的,在Object下面,现在可以通过函数来调用
let star = {
name: 'gaoyuanyuan',
age: 24,
phone: 'gaoyuanyuan188********'
};
console.log(Reflect.get(star, 'name')); // gaoyuanyuan
Reflect.set(star, 'price', '15k');
console.log(Reflect.has(star, 'price')); // true
console.log('price' in star); // true
// Object构造器上的一些方法都挪到了Reflect上,比如:
Object.defineProperty(); // 定义一个无法定义的属性会报错
Reflect.defineProperty(); // 定义一个无法定义的属性时候会返回 false
● get(target, propKey, receiver); 拦截对象展性的读取,比如 proxy.foo 和 proxy[‘foo’]。
● set(target, propKey, value, receiver); 拦截对象展性的设置,比如 proxy.foo=v或 proxy[‘foo’]=v,返回一个布尔值
● has(target, propKey); 拦截 propKey in proxy 的操作,返回一个布尔值。
● deleteProperty(target, propKey): 拦截 delete proxy [propKey]的操作,返回一个布尔值。
● ownKeys(target); 拦截 Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy) 、Object.keys(proxy),返回一个数组。该方法返回目标对象所有自身的属性的属性名,而 Object.keys() 的返回结果仅包括目标对象自身的可遍历属性。
● getOwnPropertyDescriptor(target, propKey); 拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回展性的描述对象。
● defineProperty (target, propKey, propDesc); 拦截 Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值
●preventExtensions(target); 拦截Object.preventExtensions(proxy), 返回一个布尔值
●getPrototypeOf(target); 拦截Object.getPrototypeOf(proxy), 返回一个对象
●isExtensible(target); 拦截Object.isExtensible(proxy), 返回一个布尔值
●setPrototypeOf(target, proto); 拦截 Object.setPrototypeOf(proxy, proto), 返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。
●apply(target, object, args); 拦截 Proxy 实例作为函数调用的操作。比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)
●construct(target, args): 拦截 Proxy 实例作为构造函数调用的操作,比如 new proxy(…args)