我可以在对象上下文中评估表达式吗?
Can I eval expression in object context?
美好的一天。我需要在某些对象上下文中评估表达式,但我找到的唯一解决方案是为每个对象函数创建存根:
var c = {
a : function () {
return 'a';
},
b : function () {
return 'b';
}
};
function evalInObj(c, js) {
function a() {
return c.a();
}
function b() {
return c.b();
}
return eval(js);
};
console.log(evalInObj(c, 'a() + b()'));
请告诉我正确的方法。我可以用原型来做吗?
var C = function(id) {
this.id = id;
}
C.prototype.a = function () {
return 'a' + this.id;
}
C.prototype.b = function () {
return 'b' + this.id;
}
function evalCtx(js) {
console.log(this); // C {id: 1}
return eval(js);
}
var c1 = new C(1);
evalCtx.call(c1, 'a() + b()'); // error: a is not defined
适用于仍在寻找问题(或类似)解决方案的后来者。我们可以动态创建匿名函数并在对象上下文中计算表达式,而不是使用 eval()
:
function evaluate(expression, context = {}) {
try {
// console.debug("[DEBUG] Dynamic anonymous function to be defined:'n%s", `function(${[...Object.keys(context)].join()}) {'n'use strict'; return (${expression})'n}`)
const fun = Function(...Object.keys(context), `'use strict'; return (${expression})`)
// console.debug("[DEBUG] Dynamically defined anonymous function:'n%o", fun)
const result = fun(...Object.values(context))
// console.debug("[DEBUG] Evaluation result: %o", result)
return result
} catch(error) {
if(error.message === `Unexpected token ')'`) throw SyntaxError('Unexpected token, likely at the end of expression.')
else throw error
}
}
断言:
console.assert(evaluate('a===1 && b===2', {a: 1, b: 2}) === true)
console.assert(evaluate('a===1 && b===3', {a: 1, b: 2}) === false)
console.assert(evaluate('f()', {a: 1, f: ()=>11}) === 11)
(() =>
{
// 'use strict';
function run(expression, context = {})
{
return function ()
{
return eval(expression);
}.call(context);
}
let context = {a:{b:'Bb'}};
console.log(run('this', context)); // {a:{b:'Bb'}}
console.log(run('this.a', context)); // {b:'Bb'}
console.log(run('this.a.b', context)); // 'Bb'
console.log(run('a.b', context)); // ReferenceError: a is not defined
})();
这种技术最显着的优点是它无需with
关键字即可工作,
因此即使在strict
模式下
+function()
{
// jsut pollyfills for backward browsers...
Object.prototype.keys || (Object.defineProperty(Object.prototype, 'keys', {value: function ()
{
var result = []; for (var key in this) result.push(key); return result;
}}));
Object.prototype.entries || (Object.defineProperty(Object.prototype, 'entries', {value: function ()
{
var result = []; for (var key in this) result.push([key, this[key]]); return result;
}}));
// here the magic...
function run(expression, context)
{
var variables = {};
(context instanceof Object) && context.entries().forEach(function(entry)
{
entry[0].match(/^[a-z_$][a-z0-9_$]*$/) && (variables[entry[0]] = entry[1]);
});
return (new Function('return function(' + variables.keys().join(', ') + ') { return ' + expression + '; }'))()// first get the synthetic function
.apply(context, variables.entries().map(function(entry) { return entry[1]; }));
}
var output = run("a + '#' + b", {a: 'Aa', b: 'Bb', 0: 'Zero'});
console.log(output); // Aa#Bb
}();
function runScript(ctx, js){ with(ctx){ return eval(js); }}
已关闭。谢谢大家
相关文章:
- 使用正则表达式评估电子邮件地址时出现性能问题
- Javascript-在一行中评估多个正则表达式
- 在JavaScript中评估复杂的数学表达式
- 我可以在对象上下文中评估表达式吗?
- Webpack:是否可以在编译时评估javascript表达式
- AngularJs针对多个条件评估表达式
- 评估JavaScript中给出布尔表达式的字符串
- 在 NodeJS repl 中逐个表达式地评估 Javascript 文件
- JS与C++表达式评估
- 条件表达式的评估
- JavaScript 评估,用于在某种隔离环境中的表达式
- Birt报告引擎.评估Javascript表达式时出错
- 正在评估AngularJS ng-show指令中的表达式
- 正在评估JavaScript代码中的Elisp表达式
- 正在Chrome中评估xpath表达式
- 如何评估JavaScript表达式
- 在winrt/xaml/c#应用程序中动态评估javascript表达式
- AngularJS在评估正则表达式ng模式时出现问题
- angular.js中的表达式评估
- Javascript / NodeJS 正则表达式评估在第三次尝试时失败