Angular/Typescript 评估和这个
Angular/Typescript Eval and this
所以我在理解 typescript/angular 中的 eval 如何处理这个问题时遇到了问题。有人可以帮我让 eval 在这里工作吗?这只是一个演示程序,所以忽略逻辑没有意义的事实。我只想让 eval 更新具有动态值的动态数组。
https://stackblitz.com/edit/angular-pfyt7q?file=src%2Fapp%2Fapp.component.ts
export class AppComponent {
arrTest1 = [];
arrTest2 = [];
arrTest3 = [];
constructor() {
this.TestClass.Run("this.arrTest1 = [1];");
this.TestClass.Run("this.arrTest2 = [2];");
this.TestClass.Run("this.arrTest3 = [3];");
console.log(this.arrTest1); //Logs: [] (I want: [1])
console.log(this.arrTest2); //Logs: [] (I want: [2])
console.log(this.arrTest3); //Logs: [] (I want: [3])
};
TestClass = {
Run : (pString) => {
(0, eval)(pString);
eval(pString);
}
};
}
PS:eval函数非常危险,慎用!!!
但是,因为我很友善,我将向您展示如何使您的代码工作:为了指定 eval 函数的上下文,您可以像这样使用调用 javascript 函数:
this.TestClass.Run.call(this, "this.arrTest2 = [2];");
PS2:一般情况下,你不需要使用eval函数,你甚至可以在不给出你想要的行为背后的全部代码的情况下进行解释,人们可以帮你弄清楚如何让它发挥作用。
编辑:如果你想要的行为是动态的arrays/values,你可以使用一个简单的对象并动态地添加你的属性。假设您的对象是 A:您可以使用 A[varName] 动态创建对象属性。
如果你这样做:
this.TestClass.call("this");
并且在 TestCalss 中:
console.log(eval(pString));
您会发现它记录为 window
对象。字符串 this
本身不会带上下文。如果你已经登录,window.arrTest1
,这会给你想要的结果。
所以...
您需要传递上下文:
this.TestClass.Run.call(this, "this.arrTest1 = [1]");
在你的 TestCalss 中
TestClass = {
Run : (pString) => {
return eval(pString)
}
};
Why does eval.call(this, pString) not work?
eval()
的工作方式有些不同。 eval()
不是真正的 javascript 函数。正如这里的回答:How override eval function in javascript?
正如您已经在问题中尝试过的那样,您做了类似的事情:
(0, eval)(pString); // this is an indirect call to eval
什么是间接调用?
According to ES5, all of these are indirect calls and should execute code in global scope
在你的案例中,gloabl 作用域将是空的,typescript 默认不提供全局作用域。 (据我所知)
这里写了一篇关于 eval
的非常全面的描述:
http://perfectionkills.com/global-eval-what-are-the-options/
根据上述link,以下是间接eval
调用的一些示例:
(1, eval)('...')
(eval, eval)('...')
(1 ? eval : 0)('...')
(__ = eval)('...')
var e = eval; e('...')
(function(e) { e('...') })(eval)
(function(e) { return e })(eval)('...')
(function() { arguments[0]('...') })(eval)
this.eval('...')
this['eval']('...')
[eval][0]('...')
eval.call(this, '...') <-- This is your case.
eval('eval')('...')
文章的另一段:
Not understanding what’s going on, some people unfortunately come up with rather monstrous solutions like eval.call(window, '...'), window.eval.call(window, '...') and even scarier combinations. All of those are, once again, nothing but indirect eval calls.
还有一个非常好的段落描述了为什么 (0, eval)(pString)
是间接的。请看一看。不幸的是,我可以找到任何适当的理由来证明为什么 eval.call(this, '...')
是间接的。也许我们将不得不满足 eval()
is not a real function().
这样的陈述
我在使用 eval 时遇到了类似的问题,最终使用了以下 IIFE。
表达式来自后端,例如:"Client === 123"。无法更改它们。
"eval"直接看不懂。由于在 TS 中成员变量是使用 "this" 关键字访问的。像 "this.Client" 等
一种可能的解决方法是创建一个函数并在其中添加所需的变量,然后调用 eval。
testEval(expression: HTMLInputElement) {
const result = (() => {
const Client = this.clientNumber;
return eval(expression.value);
})();
this.expressionResult = `expression: [${expression.value}], result: [${result}]`;
}
所以我在理解 typescript/angular 中的 eval 如何处理这个问题时遇到了问题。有人可以帮我让 eval 在这里工作吗?这只是一个演示程序,所以忽略逻辑没有意义的事实。我只想让 eval 更新具有动态值的动态数组。
https://stackblitz.com/edit/angular-pfyt7q?file=src%2Fapp%2Fapp.component.ts
export class AppComponent {
arrTest1 = [];
arrTest2 = [];
arrTest3 = [];
constructor() {
this.TestClass.Run("this.arrTest1 = [1];");
this.TestClass.Run("this.arrTest2 = [2];");
this.TestClass.Run("this.arrTest3 = [3];");
console.log(this.arrTest1); //Logs: [] (I want: [1])
console.log(this.arrTest2); //Logs: [] (I want: [2])
console.log(this.arrTest3); //Logs: [] (I want: [3])
};
TestClass = {
Run : (pString) => {
(0, eval)(pString);
eval(pString);
}
};
}
PS:eval函数非常危险,慎用!!!
但是,因为我很友善,我将向您展示如何使您的代码工作:为了指定 eval 函数的上下文,您可以像这样使用调用 javascript 函数:
this.TestClass.Run.call(this, "this.arrTest2 = [2];");
PS2:一般情况下,你不需要使用eval函数,你甚至可以在不给出你想要的行为背后的全部代码的情况下进行解释,人们可以帮你弄清楚如何让它发挥作用。
编辑:如果你想要的行为是动态的arrays/values,你可以使用一个简单的对象并动态地添加你的属性。假设您的对象是 A:您可以使用 A[varName] 动态创建对象属性。
如果你这样做:
this.TestClass.call("this");
并且在 TestCalss 中:
console.log(eval(pString));
您会发现它记录为 window
对象。字符串 this
本身不会带上下文。如果你已经登录,window.arrTest1
,这会给你想要的结果。
所以...
您需要传递上下文:
this.TestClass.Run.call(this, "this.arrTest1 = [1]");
在你的 TestCalss 中
TestClass = {
Run : (pString) => {
return eval(pString)
}
};
Why does eval.call(this, pString) not work?
eval()
的工作方式有些不同。 eval()
不是真正的 javascript 函数。正如这里的回答:How override eval function in javascript?
正如您已经在问题中尝试过的那样,您做了类似的事情:
(0, eval)(pString); // this is an indirect call to eval
什么是间接调用?
According to ES5, all of these are indirect calls and should execute code in global scope
在你的案例中,gloabl 作用域将是空的,typescript 默认不提供全局作用域。 (据我所知)
这里写了一篇关于 eval
的非常全面的描述:
http://perfectionkills.com/global-eval-what-are-the-options/
根据上述link,以下是间接eval
调用的一些示例:
(1, eval)('...')
(eval, eval)('...')
(1 ? eval : 0)('...')
(__ = eval)('...')
var e = eval; e('...')
(function(e) { e('...') })(eval)
(function(e) { return e })(eval)('...')
(function() { arguments[0]('...') })(eval)
this.eval('...')
this['eval']('...')
[eval][0]('...')
eval.call(this, '...') <-- This is your case.
eval('eval')('...')
文章的另一段:
Not understanding what’s going on, some people unfortunately come up with rather monstrous solutions like eval.call(window, '...'), window.eval.call(window, '...') and even scarier combinations. All of those are, once again, nothing but indirect eval calls.
还有一个非常好的段落描述了为什么 (0, eval)(pString)
是间接的。请看一看。不幸的是,我可以找到任何适当的理由来证明为什么 eval.call(this, '...')
是间接的。也许我们将不得不满足 eval()
is not a real function().
我在使用 eval 时遇到了类似的问题,最终使用了以下 IIFE。
表达式来自后端,例如:"Client === 123"。无法更改它们。
"eval"直接看不懂。由于在 TS 中成员变量是使用 "this" 关键字访问的。像 "this.Client" 等
一种可能的解决方法是创建一个函数并在其中添加所需的变量,然后调用 eval。
testEval(expression: HTMLInputElement) {
const result = (() => {
const Client = this.clientNumber;
return eval(expression.value);
})();
this.expressionResult = `expression: [${expression.value}], result: [${result}]`;
}