javascript - 是否可以使用 Function.prototype 以外的原型(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 " + 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

参见 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();

这本质上是 __proto__ 的标准化版本。

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

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

不幸的是,通过从 makeFunc 构造函数返回一个函数,而不是默认的 thismakeFunc.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/

相关文章:

javascript - Jquery $.post() 变量作用域

javascript - 使用 "ng-show"完成过滤后,如何在 angularJS 中获取过滤数据的总长度?

java - 什么都不接受也不返回什么的函数式接口(interface)

javascript - 如何在 Canvas 上使用函数

javascript - CoffeeScript、原型(prototype)继承和构造函数

javascript - 在 javascript 中,为什么在重置函数原型(prototype)后也需要重置函数原型(prototype)构造函数?

javascript - Canvas 对象和另一个对象内的多个实例?

javascript - 为什么 await 只适用于 javascript 中的异步函数?

javascript - 将鼠标悬停在 Leaflet 中的 map 时获取图层信息

javascript - 在严格模式下复制 arguments.callee