Понимание Eval Reference - PullRequest
       6

Понимание Eval Reference

0 голосов
/ 11 мая 2018

Я знаю, что есть другие темы на эту тему, но я спрашиваю снова, потому что я действительно стараюсь понять eval и как правильно его использовать, чтобы он не стал злым. Посмотрев на этот код, как я могу получить console.log(this.arrTest); для входа ['Back to Original']? Я перепробовал много вариантов, и ни один из них не работает.

Я не хочу это решение, пожалуйста: this.TestClass.Run.call(this, "this.arrTest = ['Back to Original'];"); Я хочу решение внутри класса.

Вот угловой блиц для игры: https://stackblitz.com/edit/angular-mtuvvz?file=src%2Fapp%2Fapp.component.ts

export class AppComponent  {
  arrTest = ['Original'];

  constructor() {
    this.TestClass.Run("this.arrTest = ['Back to Original'];");
    console.log(this.arrTest);
  };

  TestClass = {
    Run : (pString) => {
      this.arrTest = ['Changed']; //So this works

      eval(pString); //Why is this not working
      eval.call(this, pString); //Why is this not working
      eval.call(null, pString); //Why is this not working
      (1, eval)(pString); //Why is this not working
      (eval)(pString); //Why is this not working
      var my_eval = eval; //Why is this not working
      my_eval(pString); //Why is this not working
    }
  };

}

Я прочитал обе эти статьи, но я не понимаю их решения:

http://2ality.com/2014/01/eval.html

http://blog.klipse.tech/javascript/2016/06/20/js-eval-secrets.html

Ответы [ 2 ]

0 голосов
/ 11 мая 2018

Таким образом, это решает проблему довольно хорошо в моем сценарии:

export class AppComponent  {
  arrTest = ['Original'];

  constructor() {
    this.TestClass.Run("arrTest", "['Back to Original']");
    console.log(this.arrTest);
  };

  TestClass = {
    Run : (pKey, pValue) => {
      this.arrTest = ['Changed']; //So this works

      this[pKey] = pValue;
    }
  };

}
0 голосов
/ 11 мая 2018

В этом случае невозможно сделать eval не «злом», потому что это зло. Вместо этого следует использовать соответствующее идиоматическое решение.

  eval(pString);
  (eval)(pString);

- это способы, которые должны быть работоспособными, по сути, они одинаковы, потому что перенос eval в скобках ничего не дает. Остальные значения eval используются косвенно, что приводит к оценке кода в глобальной области видимости.

Это будет работать только с целью ES6. Можно увидеть, что класс переносит в с целью ES5, трюк var _this = this используется для передачи this из ограждающей области в функцию стрелки. this остается неизменным внутри Run метода и является TestClass объектом, а не экземпляром класса. По этой причине

this.TestClass.Run("_this.arrTest = ['Back to Original'];");

будет работать с ES5, но без цели ES6 TypeScript.

Это хороший пример, который показывает, почему eval считается «злом». Это приводит к нетипизированному, непредсказуемому, небезопасному и неоптимизированному беспорядку, которого можно избежать, следуя «хорошей» практике кодирования.

Неясно, каковы требования для TestClass.Run, но обычно такие сценарии обрабатываются с помощью обратных вызовов:

  constructor() {
    this.TestClass.Run(() => {
      this.arrTest = ['Back to Original'];
    });
    console.log(this.arrTest);
  };

  TestClass = {
    Run : (cb: () => void) => {
     // class instance can be passed to callback as an argument
     // or cb.call(this) when needed
      cb();
    }
  };

В зависимости от того, по каким причинам вводить элемент TestClass для выполнения кода внутри класса, к которому он принадлежит, это все равно может считаться неподходящим решением.

...