是否可以用Function.prototype创建另一个原型的函数? [英] Is it possible to create a function with another prototype than Function.prototype?

查看:112
本文介绍了是否可以用Function.prototype创建另一个原型的函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究JavaScript中的解析器组合器库。为此,我想创建可以像其他函数一样调用的函数,但也有成员函数,可以依次调用它们以基于它们所附加的函数(例如组合器)产生输出。

我当然可以为这样的函数添加成员:

  //我想要的函数添加额外的成员
函数hello(x){
returnHello+ x;
}

函数goodbye(x){
returnGoodbye+ x;
}

//我想作为上述函数的成员函数。
//它根据
//附加的函数创建另一个函数。
函数double(){
var that = this;
return function(x){
return that(x)+,+ that(x);
};
}

//我可以手动将它们附加到函数对象:
hello.double = double;
//调用hello.double()('Joe')结果=> 你好乔,你好乔
goodbye.double = double;
// call goodbye.double()('Joe')results in => Goodbye Joe,Goodbye Joe

我可以创建一个函数,用一个 double 成员,但我必须记得每次创建 Sayonara时调用它等功能。此外,我的问候函数会让每个成员都直接在函数对象上为每个实例。我宁愿将它们放在一个原型中,并将其作为我所有问候函数的原型。以下选项也不起作用:




  • 替换 hello .__ proto __ (非标准,在所有浏览器中都不起作用)
  • 直接修改 Function.prototype (也会将这些成员添加到所有其他函数中,但他们没有意义 - 我只想在我自己的函数中调用 double


    甚至有可能给一个函数对象一个自定义原型,或者我坚持修改我创建的每个函数对象?




    更新:我将上述示例更改为与我正在处理的实际问题更相似。这是关于如何调用函数对象而不是普通对象。最终目标是为解析器组合器提供舒适的语法,例如(很简单):

      //解析一个参数
    var arg = ...
    //解析一个参数函数名称
    var name = ...
    //分析函数调用,例如foo(x + y,test,a * 2)
    var functionCall = name.then(elem(())。then(arg.repSep(,))。then() ).into(process(...))

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

    解决方案

    是的,您可以使用 setPrototypeOf



    请参阅 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf

      function prototype(){} 
    prototype.double = function(){console.log(double); };

    函数myfunc(){}
    Object.setPrototypeOf(myfunc,prototype);

    myfunc.double();

    这实质上是 __ proto __ 的标准化版本, 。

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

     函数makeFunc(){
    return function x(){};
    }
    函数protofunc {}
    protofunc.double = {} ...
    makeFunc.prototype = protofunc;
    new makeFunc()

    不幸的是,通过从 makeFunc 构造函数,而不是默认的 this makeFunc.prototype 未应用。



    或者:

    $ $ $ $ $ $ myFunc = Object.create(protofunc, ???);

    通常我们会考虑使用 Object.create 用原型创建一个对象,但在这种情况下,没有办法指定一个函数作为对象。



    底线:唯一的选择是设置原型,可以使用 __ proto __ setPrototypeOf 来完成。这是一个ES6功能。普通的浏览器支持注意事项适用。请参阅 http://kangax.github.io/compat-table/es6/

    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.

    解决方案

    Yes, you can, using setPrototypeOf.

    See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf.

    function prototype() { }
    prototype.double = function() { console.log("double"); };
    
    function myfunc() { }
    Object.setPrototypeOf(myfunc, prototype);
    
    myfunc.double();
    

    This is essentially the standardized version of __proto__.

    There is no other way to directly create a function with a prototype other than Function.prototype. Consider:

    function makeFunc() {
        return function x() { };
    }
    function protofunc { }
    protofunc.double = { }...
    makeFunc.prototype = protofunc;
    new makeFunc()
    

    Unfortunately, by returning a function from the makeFunc constructor, rather than the default this, the makeFunc.prototype is not applied.

    Or:

    myFunc = Object.create(protofunc, ???);
    

    Normally we think of using Object.create to create an object with a prototype, but in this case, there's no way to specify a function as being the object.

    Bottom line: the only alternative is to set the prototype explicitly, which you can do either with __proto__, or setPrototypeOf. This is an ES6 feature. Normal browser support caveats apply. See http://kangax.github.io/compat-table/es6/.

    这篇关于是否可以用Function.prototype创建另一个原型的函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆