组成如何:
const os = require('os');
const proxy = new Proxy(os, {});
Object.getOwnPropertyNames(os).forEach(k => {
var v = os[k];
if(typeof v === "function") proxy[k] = v.bind(os);
});
//the `!!` because I don't want the actual print
//only a `true` or an `Error`
console.log(!!os.cpus());
console.log(!!proxy.cpus());
console.log(!!proxy.cpus.apply(proxy, []));
而这一切都作为一个实用函数来“替换” new Proxy()
,哪里handler.bindTargetFunctions
可以
- 要绑定的 keyNames 数组(所以你可以具体)
- 或任何真值或假值,以确定目标上的所有功能是否应绑定
编码:
function proxy(target, handler){
const _proxy = new Proxy(target, handler);
if(handler.bindTargetFunctions){
let bindTargetFunctions = handler.bindTargetFunctions;
if(!Array.isArray(bindTargetFunctions)){
bindTargetFunctions = Object.getOwnPropertyNames(target)
.filter(key => typeof target[key] === "function");
}
bindTargetFunctions.forEach(key => {
_proxy[key] = target[key].bind(target);
});
}
return _proxy;
}
const os = proxy(require('os'), { bindTargetFunctions: true });
//or
//const os = proxy(require('os'), { bindTargetFunctions: ["cpus"] });
console.log(os.cpus());
编辑:
目前,我尝试直接在我的 get 处理程序中绑定函数(请参阅 github.com/FranckFreiburger/module-invalidate/blob/master/…),我的解决方案的缺点是每次访问函数都会返回一个新绑定。
我在评论中提到了缓存。这就是这个缓存的样子:
function createProxy(mod){
var cache = Object.create(null);
return new Proxy(function(){}, {
get(target, property, receiver) {
var val = Reflect.get(mod._exports, property, receiver);
if(typeof val === "function"){
if(!(property in cache) || cache[property].original !== val){
cache[property] = {
original: val,
bound: bal.bind(mod._exports)
}
}
val = cache[property].bound;
}else if(property in cache){
delete cache[property];
}
return val;
}
});
}
不,我不认为这个缓存是一个普通的对象。不是因为它继承自 null,而是因为从逻辑上讲,对我来说这是一个字典/地图。而且我不知道您为什么要扩展或代理特定字典的任何原因。