I am working on a parser combinator library in JavaScript. For that I want to create functions that can be called like any other functions, but also have member functions that can be called in turn to produce output based on the function they are attached to (e.g. combinators).
I can of course add members to functions like this:
//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"
I could create a function that augments all my functions with a double
member, but I would have to remember to call it every time I create a Hey
, Sayonara
, etc. function. Also my greeting functions would have all those members each, directly on the function object, for each instance. I would prefer to put them all in one prototype and make this the prototype of all my greeting functions. The following options don't work either:
- replacing
hello.__proto__
(nonstandard, won't work in all browsers)
- modifiying
Function.prototype
directly (would add those members to all other functions as well, but they do not make sense there - I only want to call double
on a set of my own functions)
Is it even possible to give a function object a custom prototype or am I stuck with modifying each function object I create?
Update: I changed the above example to be more similar to the actual problem I am working on. This is about modyfing function objects not normal objects. The final goal is to enable a comfortable syntax for parser combinators, e.g. (much simplified):
//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(…))
I want to be able to add members to a set of functions so, when these members are called, they return new functions based on the function on which they were called. This is to be used for parser combinators / monadic parsers.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…