【问题标题】:Detecting when an object called is called by . accessor or as function call检测调用的对象何时被调用。访问器或作为函数调用
【发布时间】:2018-03-05 12:43:22
【问题描述】:

我有以下对象

let o = {
    fn:()=>1,
    a:2
}

如果我说o() 我希望调用被代理到fn 并且如果我说o.a 应该返回a 的值,是否可以完全按照它呈现的那样?

它更像是一个对象的未命名默认函数

【问题讨论】:

  • o 成为自己的功能:let o = () => 1; o.a = 2

标签: javascript ecmascript-6 es6-proxy


【解决方案1】:

由于 JS 中的函数是对象,你可以通过属性对其进行扩展:

const o = Object.assign(() => o.fn(), {
  a: 5,
  fn: () => 1
});

console.log(o());
console.log(o.a);

如果你需要覆盖不可写的Function属性,比如name,你可以先创建函数,然后使用Object.defineProperties()添加属性,将不可写变为可写。

注意:这感觉已经够骇人听闻了,而且不会缺少函数的不可写属性。我建议避免它。

const o = () => o.fn();

Object.defineProperties(o, {
  fn: { value: () => 1 },
  a: { value: 5 },
  name: { writable: true, value: 'whatever' },
});

console.log(o());
console.log(o.a);
console.log(o.name);

【讨论】:

  • 当对象有一个名为 name 的属性时它会爆炸!有没有一种神奇的方法可以解决这个问题,或者我只需要避免使用这些道具名称?!
【解决方案2】:

它是否可能与它所呈现的完全一样?

不,你不能,因为那只是一个 key-value 对象而不是函数。


您需要将该对象声明为函数:

  • 在函数o内声明函数fn
  • 为当前函数o设置一个名为a的属性。

let o = () => {
    fn = () => 1;
    o.a = 2;
    
    return fn();
};

console.log(o());
console.log(o.a);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 函数对象,因此也可以有自己的键值属性...
  • @Alnitak 是的,但在这种情况下,它只是一个 key-value 对象,没有别的。
  • 我主要是想说这种关系不是传递的。函数是对象,但(大多数)对象不是函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 1970-01-01
  • 2010-12-11
  • 2015-02-16
  • 1970-01-01
  • 2012-05-28
相关资源
最近更新 更多