Javascript 是否可以使用function.prototype以外的其他原型创建函数?
我正在用JavaScript开发一个解析器组合器库。为此,我想创建可以像其他函数一样调用的函数,但也有可以依次调用的成员函数,以便根据它们所附加的函数(例如,组合器)生成输出 我当然可以将成员添加到如下函数: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 " +
//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, ???);