在调用对象的情况下是否可以将功能分配给对象?

时间:2019-04-14 08:48:56

标签: javascript

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

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

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

它可以满足我的需求,但是我更喜欢使用dumbtion()而不是dumbtion.do()。无论如何,可以使用javascript来实现这一点吗?

5 个答案:

答案 0 :(得分: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 :(得分: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使用它,但最好不要使用它。)

答案 2 :(得分: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);

答案 3 :(得分:1)

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

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();

答案 4 :(得分: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

但是您将失去随后访问其他属性的可能性。