Javascript 是否可以使用function.prototype以外的其他原型创建函数?

Javascript 是否可以使用function.prototype以外的其他原型创建函数?,javascript,function,prototype,Javascript,Function,Prototype,我正在用JavaScript开发一个解析器组合器库。为此,我想创建可以像其他函数一样调用的函数,但也有可以依次调用的成员函数,以便根据它们所附加的函数(例如,组合器)生成输出 我当然可以将成员添加到如下函数: //the functions I want to add additional members to function hello(x) { return "Hello " + x; } function goodbye(x) { return "Goodbye " +

我正在用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
等函数时都要调用它。另外,对于每个实例,我的问候语函数都会直接在函数对象上包含所有这些成员。我更愿意把它们都放在一个原型中,让它成为我所有问候功能的原型。以下选项也不起作用:

  • 替换
    hello.\uuuu proto\uuuuu
    (非标准,无法在所有浏览器中工作)
  • 直接修改
    Function.prototype
    (也会将这些成员添加到所有其他函数中,但它们在那里没有意义-我只想对我自己的一组函数调用
    double
甚至可以给一个函数对象一个自定义原型,还是我一直在修改我创建的每个函数对象


更新:我更改了上述示例,使其更接近我正在处理的实际问题。这是关于修改函数对象而不是普通对象。最终目标是为解析器组合器启用一种舒适的语法,例如(大大简化):


我希望能够将成员添加到一组函数中,这样,当调用这些成员时,它们会根据调用它们的函数返回新函数。这将用于解析器组合器/一元解析器

有两种不同的选择。我认为你应该考虑对象和继承,而不是函数和全局。在上面的示例中,您基本上是想让“world”继承hello方法集。(或者你想让“你好”继承“世界”?)

您应该从阅读本文开始:

下面是一些使用“原型继承”演示继承的简单代码


虽然我知道您要求的解决方案没有使用Function.prototype,但我想知道您是否考虑过可以有条件地链接执行行为,以便像double()这样的Function.prototype函数根据“类”实例允许不同行为共存

// This could also be adapted to itself be on Function.prototype
function chainConditions () {
    var args = arguments;
    return function () {
        for (var i=0, argl = args.length; i < argl; i++) {
            var ret = args[i].apply(this, arguments);
            if (typeof (ret) !== 'undefined') { // If you want to allow undefined to be returnable, you could instead add this to a try-catch and ignore those which throw exceptions or a certain exception
                return ret;
            }
        }
    };
}
Function.prototype.double = function () {
    if (this.prototype instanceof Salutation) {
        var that = this;
        return function(x) {
            return that(x) + ", " + that(x);
        };
    }
};
Function.prototype.double = chainConditions(
    function () {
        if (this.prototype instanceof Tennis) {
            var that = this;
            return function(x) {
                return that(x) + ", " + that(x);
            };
        }
    },
    Function.prototype.double
);


function Salutation () {}

function Hello(x) {
    return "Hello " + x;
}

function Goodbye(x) {
    return "Goodbye " + x;
}
Goodbye.prototype = new Salutation();


function Tennis () {
}
function TennisPlayer (x) {   
    return x + ' serve';
}
TennisPlayer.prototype = new Tennis();



alert(TennisPlayer.double()('Forehand')); // Forehand serve, Forehand serve

alert(Goodbye.double()('Yellow Brick Road')); // Goodbye Yellow Brick Road, Goodbye Yellow Brick Road

alert(Hello.double()('Yellow Brick Road')); // does not work as we did not use Hello.prototype = new Salutation();
//这也可以在Function.prototype上进行自我调整
函数条件(){
var args=参数;
返回函数(){
for(变量i=0,argl=args.length;i
通过允许一个函数用于类类型检查(例如,将function.prototype上的所有称呼方法分组为一个类型检查),以及另一个函数接受与它们的条件行为相关的方法列表,应该能够进一步抽象这一点


虽然它使用自己的API,但它相当不突兀,甚至可以让它与Function.prototype上的现有方法一起工作,而这些方法不会通过抛出异常(只需确保最后包含任何预先存在的方法)。

对您的问题的简短回答是:是的

function Parent() {
    // constructor
}

function Child() {
    // constructor
}

Child.prototype = new Parent();
以下是如何向子类添加方法:

Child.prototype.someMethod = function() {
    // do something
}

不幸的是,我以面向对象的方式使用Javascript已经有很长一段时间了,但我相信有一些解决方案可以使语法更加清晰。

是的,您可以使用
setPrototypeOf

这基本上是
\uuuu proto\uuuu
的标准化版本

除了function.prototype之外,没有其他方法可以直接使用原型创建函数。考虑:

function makeFunc() {
    return function x() { };
}
function protofunc { }
protofunc.double = { }...
makeFunc.prototype = protofunc;
new makeFunc()
不幸的是,通过从
makeFunc
构造函数返回函数,而不是从默认的
this
返回函数,
makeFunc.prototype
不会应用

或:

通常我们考虑使用
Object.create
来创建一个带有原型的对象,但在这种情况下,无法将函数指定为对象


底线:唯一的替代方法是显式地设置原型,您可以使用
\uuuuu proto\uuuuu
setPrototypeOf
进行设置。这是ES6的一个特性。正常浏览器支持警告适用。请参阅。

他正在尝试修改函数对象,而您正在修改您需要的对象
Child.prototype.someMethod = function() {
    // do something
}
function prototype() { }
prototype.double = function() { console.log("double"); };

function myfunc() { }
Object.setPrototypeOf(myfunc, prototype);

myfunc.double();
function makeFunc() {
    return function x() { };
}
function protofunc { }
protofunc.double = { }...
makeFunc.prototype = protofunc;
new makeFunc()
myFunc = Object.create(protofunc, ???);