是否有可能向对象提供一个函数,而无论其名称如何,该函数总是在被调用时被调用?
或者换句话说:是否有可能具有适用于所有可能名称的功能?
也许对象的prototype
有所变化?
下面是该方法的示例:
const o = {
[magic here]: () => 1;
};
o.foo(); // returns 1
o.bar(); // returns 1
o.baz(); // returns 1
我正在尝试一种铁路编程方法。
基本上,我希望这是自动化的,而不是手动检查对象是null
还是undefined
并做出相应的反应。
示例:
// checks if object is null and returns a object, that can be called however without crashing
// thanks to T.J. Crowder's answer
function saveNull(o){
if(o !== null) return o;
const p = new Proxy({}, {
get(target, prop, receiver) {
return () => p;
},
});
return p;
}
const a = " abc"; // could be null
const b = a.toUpperCase().trim(); // could crash
const c = a ? a.toUpperCase.trim() : null; // approach 1
const d = a && a.toUpperCase().trim(); // approach 2
const e = saveNull(a).toUpperCase().trim(); // approach 3
我发现最后一种方法更具可读性和趣味性。
答案 0 :(得分:10)
您可以在ES2015及更高版本中使用Proxy
来执行此操作;您无法在ES5及更低版本中做到这一点。
如果您确实希望每个可能的属性都返回此魔术函数,那么这很简单:
const obj = {};
const magic = () => 1;
const p = new Proxy(obj, {
get(target, prop, receiver) {
return magic;
}
});
console.log(p.foo()); // returns 1
console.log(p.bar()); // returns 1
console.log(p.baz()); // returns 1
如果要允许对象具有其他属性,如果存在则返回其值,否则返回魔术函数,则可以使用Reflect.has
来查看对象是否具有该属性,并且然后Reflect.get
来获取它:
const obj = {
notMagic: 42
};
const magic = () => 1;
const p = new Proxy(obj, {
get(target, prop, receiver) {
// If the object actually has the property, return its value
if (Reflect.has(target, prop)) {
return Reflect.get(target, prop, receiver);
}
// Return the magic function
return magic;
}
});
console.log(p.foo()); // returns 1
console.log(p.bar()); // returns 1
console.log(p.baz()); // returns 1
console.log(p.notMagic); // 42
如果您希望函数将this
视为对象,则可以使用非箭头函数,并且可能使用bind
来简化事情:
const obj = {
notMagic: 42
};
const magic = function() {
console.log(this === obj);
return 1;
}.bind(obj);
const p = new Proxy(obj, {
get(target, prop, receiver) {
// If the object actually has the property, return its value
if (Reflect.has(target, prop)) {
return Reflect.get(target, prop, receiver);
}
// Return the magic function
return magic;
}
});
console.log(p.foo()); // returns 1
console.log(p.bar()); // returns 1
console.log(p.baz()); // returns 1
console.log(p.notMagic); // 42