Как определить, была ли функция вызвана нормально или как тег с литералом шаблона? - PullRequest
2 голосов
/ 04 июля 2019

Я хотел бы создать функцию, которую можно вызывать в обычном режиме:

myFn(arg1, arg2)

Или как помеченный шаблонный литерал:

myFn`text ${someVar}`

В реализации myFn возможно ли определить, был ли он вызван нормально или как тег с литералом шаблона? Аргументы, передаваемые литералу шаблона, имеют определенный шаблон (первый аргумент - это массив строк, дополнительные аргументы, если таковые существуют, будут на единицу меньше, чем длина массива в первом аргументе), поэтому я мог определить, исходя из этого , Но кто-то может теоретически передать тот же шаблон аргумента обычному вызову функции.

Есть ли какой-нибудь особый способ обнаружить способ, которым он был вызван, помимо определения шаблона аргумента?

1 Ответ

2 голосов
/ 04 июля 2019

Я не думаю, что есть какой-либо способ проверки с абсолютной уверенностью, но вы можете добавить некоторые вещи к проверке аргументов, чтобы уменьшить вероятность случайного вызова с аргументами, удовлетворяющими вашим проверкам.При вызове в качестве тега шаблона первым аргументом будет массив с хотя бы одним элементом, он будет заморожен, и у него будет свойство с именем raw, которое является массивом такой же длины.Вы также можете проверить количество оставшихся аргументов, как вы уже упоминали:

function myFn ( arg1, ...rest ) {
  const isTag = !!(
    arg1 && arg1.length > 0 && arg1.raw && arg1.raw.length === arg1.length &&
    Object.isFrozen( arg1 ) &&
    rest.length + 1 === arg1.length
  );

  console.log( isTag );
}

// isTag === true
myFn`test`;
myFn`${0} ${1}`;
myFn``;

// isTag === false
myFn( );
myFn( ['test'] );

Вы можете пойти немного дальше, проверив, что все элементы в массиве и в raw являются строками, и даже проверьте, что они являются одинаковыми строками после замены escape-последовательностей.в необработанных строках с соответствующими символами.Я думаю, что это, вероятно, не нужно, потому что это не сделает более трудным для кого-то целенаправленно обманывать вашу функцию (хотя это ограничит входы, которые они могут использовать, чтобы обмануть ее), и уже маловероятно, что вышеупомянутый тест завершится неудачно, есликто-то пытается целенаправленно обмануть его.

...