Какова альтернатива использованию eval (myFunctionName) в качестве обратного вызова в приемнике событий? - PullRequest
1 голос
/ 03 октября 2019

Я задал этот вопрос неправильно, поэтому я начинаю снова, начиная со специфики проблемы, с которой я борюсь, а не с общих особенностей проблемы.

У меня есть объект, в котором значения являются строками. Они в значительной степени должны быть строками, потому что они извлекаются из пользовательских атрибутов data-* HTML5, и я действительно не хочу начинать писать javascript внутри атрибутов HTML, как в 1999 году.

Вот пример одного изПользовательские data-* атрибуты:

data-event="{«eventListener» : «transitionend», «eventAction» : «showText»}"

Как видите, в основном это строка JSON, слегка измененная, так что она может принимать форму значения атрибута HTML.

Я быхотел бы иметь возможность проанализировать этот пользовательский атрибут data-* и перевести его в следующий javascript:

parentElement.addEventListener('transitionend', showText, false);

Чтобы сделать это, мне нужно:

  1. Заменить « и » символов с " символом
  2. JSON.parse результирующего значения в объекте
  3. Создайте параметр useCapture, если он не существует (как в этом примере)
  4. Тогда для меня просто (почти) просто создать оператор addEventListener

На самом деле - конечно - я получаю следующее утверждение:

parentElement.addEventListener('transitionend', 'showText', false);

, который не работает, потому что я не могуoke 'showText' - это просто строка, она не указывает на функцию.

Самый простой способ исправить это, создать вместо этого оператор:

parentElement.addEventListener('transitionend', eval('showText'), false);

which равно эквивалентно:

parentElement.addEventListener('transitionend', showText, false);

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


Вопрос: Это неверноили нежелательно в Javascript принимать строку, которая является именем функции, и обращаться к этой функции и выполнять ее, используя eval() в строке?

Если это нецелесообразно, какова альтернатива, когдаЯ знаю имя функции и хочу вставить ее в обработчик событий?

Если мне лучше избежать этого:

parentElement.addEventListener('transitionend', eval('showText'), false);

что мне использовать вместо этого?

Или ... это вполне приемлемо дляиспользовать eval() в некоторых ситуациях - и это одна из них?

Ответы [ 2 ]

1 голос
/ 03 октября 2019

В ответ на обновление вам будет лучше поместить все обработчики событий в объект, а не в глобальное пространство имен, а именно:

до:

function showText(event) {
   ...
}

function anotherHandler(event) {
   ...
}

после:

const myActions = {
   showText(event) {
      ...
   },
   anotherHandler(event) {
      ...
   }
}

И затем, после того, как вы проанализировали атрибут data и получили что-то вроде этого:

data = {"eventListener" : "transitionend", "eventAction" : "showText"}

связать обработчик следующим образом:

parentElement.addEventListener(
     data.eventListener,
     myActions[data.eventAction],
     false)

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

1 голос
/ 03 октября 2019

Если ваша функция находится в глобальной области видимости, она делает это:

myElement.addEventListener('click', window[myObject.function1], false);

Квадратные скобки являются просто альтернативным синтаксисом для . - но они допускают имена переменных свойств.

Проверьте это:

const obj = { a: 'Hello this is obj.a' };

const key = 'a';

console.log(obj.a);
console.log(obj['a']);
console.log(obj[key]);
...