是否可以编写适用于每个名称的函数?

Sho*_*omo 3 javascript prototype

是否可以为调用函数的对象提供一个函数,无论其名称如何?

或者换句话说:是否有可能具有适用于所有可能名称的功能?

也许随着对象的变化prototype

这里是一个如何工作的例子:

const o = {
  [magic here]: () => 1;
};

o.foo(); // returns 1
o.bar(); // returns 1
o.baz(); // returns 1

Run Code Online (Sandbox Code Playgroud)

编辑以澄清我为什么要这样做:

我正在尝试使用铁路编程方法。基本上,我希望这是自动化的,而不是手动检查对象是否为nullundefined做出相应的反应。

例:


// 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

Run Code Online (Sandbox Code Playgroud)

我发现最后一种方法更具可读性和试验性。

T.J*_*der 10

您可以Proxy在ES2015及更高版本中使用;您无法在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
Run Code Online (Sandbox Code Playgroud)

如果要允许对象具有其他属性,并在存在它们的情况下返回它们的值,而在没有魔术函数的情况下返回它们的值,则可以使用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
Run Code Online (Sandbox Code Playgroud)

如果您希望函数以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
Run Code Online (Sandbox Code Playgroud)