我正在使用 JavaScript 开发一个解析器组合器库。为此,我想创建可以像任何其他函数一样调用的函数,但也有可以依次调用的成员函数,以根据它们所附加的函数(例如组合器)产生输出。
我当然可以像这样给函数添加成员:
//the functions I want to add additional members to
function hello(x) {
return "Hello " + x;
}
function goodbye(x) {
return "Goodbye " + x;
}
//The function I want as a member of the above functions.
//it creates another function based on the function it is
//attached to.
function double() {
var that = this;
return function(x) {
return that(x) + ", " + that(x);
};
}
//I can attach them manually to the function objects:
hello.double = double;
//calling hello.double()('Joe') results in => "Hello Joe, Hello Joe"
goodbye.double = double;
//calling goodbye.double()('Joe') results in => "Goodbye Joe, Goodbye Joe"
我可以创建一个函数,用一个 double
成员来扩充我的所有函数,但是我必须记住每次创建一个 Hey
时调用它,Sayonara
等函数。此外,我的问候函数将在每个实例中直接在函数对象上拥有所有这些成员。我更愿意将它们全部放在一个原型(prototype)中,并将其作为我所有问候功能的原型(prototype)。以下选项也不起作用:
- 替换
hello.__proto__
(非标准,不适用于所有浏览器) - 直接修改
Function.prototype
(也会将这些成员添加到所有其他函数中,但它们在那里没有意义 - 我只想调用double
一套我自己的功能)
甚至可以为函数对象提供自定义原型(prototype),还是我必须修改我创建的每个函数对象?
更新:我更改了上面的示例,使其更接近我正在处理的实际问题。这是关于修改 函数对象 而不是普通对象。最终目标是为解析器组合器启用舒适的语法,例如(大大简化):
//parses one argument
var arg = …
//parses one function name
var name = …
//parses a function call, e.g. foo(x+y, "test", a*2)
var functionCall = name.then(elem("(")).then(arg.repSep(",")).then(")").into(process(…))
我希望能够向一组函数 添加成员,这样,当调用这些成员时,它们会根据调用它们的函数返回新函数。这将用于解析器组合器/单子(monad)解析器。
最佳答案
是的,你可以,使用 setPrototypeOf
。
function prototype() { }
prototype.double = function() { console.log("double"); };
function myfunc() { }
Object.setPrototypeOf(myfunc, prototype);
myfunc.double();
这本质上是 __proto__
的标准化版本。
除了 Function.prototype 之外,没有其他方法可以直接创建带有原型(prototype)的函数。考虑:
function makeFunc() {
return function x() { };
}
function protofunc { }
protofunc.double = { }...
makeFunc.prototype = protofunc;
new makeFunc()
不幸的是,通过从 makeFunc
构造函数返回一个函数,而不是默认的 this
,makeFunc.prototype
没有被应用。
或者:
myFunc = Object.create(protofunc, ???);
通常我们会想到使用 Object.create
来创建一个带有原型(prototype)的对象,但在这种情况下,没有办法将函数指定为对象。
底线:唯一的选择是显式设置原型(prototype),您可以使用 __proto__
或 setPrototypeOf
来实现。这是 ES6 的特性。普通浏览器支持警告适用。参见 http://kangax.github.io/compat-table/es6/ .
关于javascript - 是否可以使用 Function.prototype 以外的原型(prototype)创建函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5135326/