扩展功能原型

时间:2012-05-10 06:22:07

标签: javascript prototype

我希望能够在javascript中扩展函数原型(也就是说,为所有函数添加一个函数)。 目的是将其转换为另一种语言之间的交换格式(即ruby,它只能通过字符串[在此特定设置中]进行通信)。我已经有了一个系统,所以我可以通过在ruby对象上定义to_js方法和在javascript对象上定义to_ruby方法来传递其他类型,如此

Number.prototype.to_ruby = function () { return this.toString(); }

这适用于我想要的其他所有内容,但不适用于功能。我可以通过执行以下操作让它在chrome中工作:

_empty = function() {};
_empty.__proto__.to_ruby = function () {
    return 'JSFunction.new(' + this.toString().to_ruby() + ')';
};

但这在IE中不起作用(这是系统的要求)。

我知道我有一个对象可以通过ID或类似方式跟踪函数,但我不能保证它们将与创建它们的同一个实例一起使用。

所有其他方法都失败我只能写一个函数处理特殊情况(即isFunction(instance) ? fn_to_ruby(instance) : instance.to_ruby(),但我宁愿保留这个模型。

3 个答案:

答案 0 :(得分:4)

正如Slace所说,你可以通过将方法添加到Object.prototype来将该方法添加到所有对象中,但这并不是真正的犹太方法,因为它可能会影响对于..in循环的错误编写。

您可以通过Function.prototype

将其添加到功能中
Function.prototype.to_ruby = function() {
  return this.toString();
}

然而,一般规则是您不应该修改内置对象,主要是因为您永远不知道它何时会回来困扰您(例如,新版本的ECMAScript实现了具有相同名称的属性)。也许你最好写一个toRuby函数:

function toRuby(obj) {
  return obj.toString();
}

但您也可以使用+运算符与字符串连接以隐式调用toString方法:

'' + obj; // returns obj.toString()

将返回与上述完全相同的结果。你的选择。

答案 1 :(得分:2)

__proto__不是标准属性。试试这种方法:

(function(){}).constructor.prototype.to_ruby = function(){
    return 'JSFunction.new(' + this.toString().to_ruby() + ')';
};

答案 2 :(得分:-1)

__proto__不是任何JavaScript标准的一部分,它只是某些浏览器制造商决定实施的伪标准。 IE是尚未实现它的那个。

如果要在JavaScript类型系统中修改任何类型,则必须修改Object原型:

Object.prototype.foo = function () { console.log('foo'); };
(1).foo();
'asd'.foo();
(true).foo();
({ bar: 'baz' }).foo();