我有一种叫做动作的对象。它们的构造如下:
const Action = (name, type, cb) => ({
name,
type,
do: cb
})
const dumbtion = Action('dumb', 'system', () => { console.log("I'm dumb")})
它可以满足我的需求,但是我更喜欢使用dumbtion()
而不是dumbtion.do()
。无论如何,可以使用javascript来实现这一点吗?
答案 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
返回一个关闭参数name
和type
的函数:
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
本身上的type
和dumbtion
,则函数是对象,因此可以向其添加属性:
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
并返回一个新函数,该函数在运行时将使用cb
和name
作为参数调用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();
如果您还想访问那些属性(使用不同名称,因为name
是Function
的现有属性),您可以执行以下操作:
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
但是您将失去随后访问其他属性的可能性。