是否可以在调用对象时为对象分配函数?

问题描述 投票:1回答:5

我有一种叫做action的对象。它们的构造如下:

const Action = (name, type, cb) => ({
   name,
   type,
   do: cb
})

const dumbtion = Action('dumb', 'system', () => { console.log("I'm dumb")})

它可以满足我的需求,但我更喜欢使用dumbtion()而不是dumbtion.do()。反正有没有在JavaScript中实现这一点?

javascript
5个回答
1
投票

您可以使用closure并返回一个新函数,在运行时将调用cb并使用nametype作为参数。

function createAction(name, type, cb) {
  return function() {
    cb(name, type);
  };
}

const dumbtion = createAction('dumb', 'system', (name, type) => {
  console.log(`I'm '${name}' of type: '${type}'`);
});

dumbtion();

如果您还想访问这些属性(具有不同的名称,因为nameFunction的现有属性),您可以执行以下操作:

function createAction(name, type, cb) {
  const result = function() {
    return cb(result._name, result._type);
  };
  result._name = name;
  result._type = type;
  return result;
}

const dumbtion = createAction('dumb', 'system', (name, type) => {
  console.log(`I'm '${name}' of type: '${type}'`);
});

dumbtion();

dumbtion._name = "not dumb";
dumbtion._type = "not system";

dumbtion();

虽然如果使用Object.defineProperty你会有更多的控制权:

function createAction(name, type, cb) {
  const result = function() {
    return cb(name, type);
  };
  Object.defineProperty(result, "_name", {
    get: function() {
      return name;
    },
    set: function(value) {
      name = value;
    }
  });
  Object.defineProperty(result, "_type", {
    get: function() {
      return type;
    },
    set: function(value) {
      type = value;
    }
  });
  return result;
}

const dumbtion = createAction('dumb', 'system', (name, type) => {
  console.log(`I'm '${name}' of type: '${type}'`);
});

dumbtion();

dumbtion._name = "not dumb";
dumbtion._type = "not system";

dumbtion();

2
投票

通过将属性直接分配给函数,然后返回函数,可以:

const Action = (actionName, type, cb) => (
  Object.assign(cb, { actionName, type })
)
const dumbtion = Action('dumb', 'system', () => { console.log("I'm dumb")})

dumbtion();
console.log(dumbtion.type);

但这不是一个好主意 - 函数通常不应该添加非标准属性。我更喜欢你目前使用的代码。

(注意,不能使用属性name,因为它是在函数上保留的 - 它不能被重新赋值)


1
投票

不是函数的对象不能被视为一个对象。

您可以创建一个函数并将属性赋值给它。

const action = (name, type, cb) => {
   const func = function () {
       return cb.apply(this, arguments);
   };
   func.name = name;
   func.type = type;
   func.do = cb;
   return func;
};

const modified = action('a name', 'system', () => { console.log("Foo")})

modified();
console.log(modified.type);

1
投票

你可以让Action返回一个关闭参数nametype的函数:

const Action = (name, type, cb) => () => cb(name, type);

const dumbtion = Action('dumb', 'system', (name, type) => {
    console.log(`I'm dumb, name = ${name}, type = ${type}`);
});

dumbtion();

在这个具体的例子中,Action并没有真正起到太多作用,但是一般模式非常有用。

如果你想在name本身访问typedumbtion,函数就是对象,所以你可以为它们添加属性:

const Action = (xname, type, cb) => {
  cb.xname = xname;
  cb.type = type;
  return cb;
};

const dumbtion = Action('dumb', 'system', function cb() {
    console.log(`I'm dumb, name = ${cb.xname}, type = ${cb.type}`);
});

dumbtion();
console.log(dumbtion.xname);
console.log(dumbtion.type);

注意我在那里使用了一个命名函数表达式,以便回调可以在调用中按名称访问自己。另请注意,您不能使用name,它是函数的预定义属性。 (好吧,好吧,你可以通过Object.defineProperty使用它,但最好不要。)


0
投票

只需从你的function函数返回一个Action,它将.do称为引擎盖:

const Action = (name, type, cb) => () => ({
   name,
   type,
   do: cb
}).do();

const dumbtion = Action('dumb', 'system', () => { console.log("I'm dumb")})

dumbtion(); // <-- calls `.do()` internally

但是你将失去访问其他属性的可能性。

© www.soinside.com 2019 - 2024. All rights reserved.