2010-03-11 72 views
2

我怀疑这是可能的,我一定会在生产环境中做到这一点是一个令人印象深刻的坏主意。这只是那些假设的“我不知道......我能......”的事情之一。关于浏览器JavaScript引擎的理论问题

我想知道是否可以修改或扩展浏览器JavaScript引擎在运行时解析代码的方式。例如:如果我试图用C#风格的lambda语法在JavaScript:

var x = myJsObjCollection.Where(a=>a.ID == 2); 

我可以修改脚本的解析和拦截拉姆达代码,并解析它自己?

回答

3

我对此表示怀疑。

解析并执行javascript的引擎位于客户端的浏览器上,因此不能被任何网站修改或更改(我希望)。

潜在地,您可以使用JavaScript支持的类型和语法来描述lambda表达式,然后拥有自己的JavaScript库,将其展开为有效的JavaScript调用。

但是,它不会很有用,因为javascript函数已经非常灵活。你在上面有效的JS代码将类似于等价的C#委托:

var x = myJsObjCollection.Where(function() { if (this.ID == 2) return this; }); 

这是不是一大堆更多的工作类型。

更新

采取Bob's Idea几个步骤进一步,你可能会写这样的事:

function lambda(vName, comparison) 
{ 
    var exp = new RegExp("\\b" + vName + "\\.", "g"); 
    comparison = comparison.replace(exp, "arg."); 
    return function(arg) { 
     var result; 
     eval("result = " + comparison + ";"); 
     return result; 
    }; 
} 

然后你在哪里函数看起来是这样的:

Array.prototype.Where = function(lambdaFunc) { 
    var matches = [];  
    for (var i in this) 
    { 
     if (lambdaFunc(this[i])) 
      matches[matches.length] = this[i] 
    } 
    return matches; 
}; 

你可以称之为:

var x = myJsObjCollection.Where(lambda("a", "a.ID == 2")); 

工作示例http://jsbin.com/ifufu/2/edit

+0

很酷。你也可以调用split,这样你就可以将lambda参数保留为“a => a.ID === 2”这样的字符串,并在“=>”上分开......可能需要一些解析来修剪空格 – Bob 2010-03-11 01:53:44

1

在JavaScript中没有直接的方法来做到这一点。你可以得到最接近的就是编写你自己的eval类型的函数,它可以解释你想要的任何代码。

或者,让V8 JavaScript引擎源代码,做一些改变这一点,看看你是否可以得到它在Chrome中实现某种方式:)

+0

自定义eval的想法是好的。像'lambdaEval(“a => a.ID == 2”);'。但这将是很多解析。 – Joel 2010-03-11 00:31:09

+0

检查我的答案重新:functional.js :-) – Pointy 2010-03-11 01:03:45