Обратные вызовы вызова функции

Я не уверен, как это объяснить, но когда я бегу

console.log`1`

В Google Chrome я получаю вывод, как

console.log`1`
VM12380:2 ["1", raw: Array[1]]

Почему обратный вызов вызывает функцию журнала и почему он создает индекс raw: Array[1]?

Вопрос, поднятый в комнате JS компанией Catgocat, но ответы не имели смысла, кроме того, что касалось шаблонных строк, которые на самом деле не подходили, почему это происходит.

2 ответа

Решение

Он называется Tagged Template в ES-6, подробнее о них можно прочитать здесь. Забавно, я нашел ссылку в помеченном разделе самого чата.

Но соответствующая часть кода ниже (вы можете создать фильтрованную сортировку).

function tag(strings, ...values) {
  assert(strings[0] === 'a');
  assert(strings[1] === 'b');
  assert(values[0] === 42);
  return 'whatever';
}
tag `a${ 42 }b`  // "whatever"

По сути, это просто пометка "1" с помощью функции console.log, как это было бы с любой другой функцией. Функции тегирования принимают проанализированные значения строк шаблона и значения отдельно, для которых могут быть выполнены дальнейшие задачи.

Бабель передает приведенный выше код

var _taggedTemplateLiteralLoose = function (strings, raw) { strings.raw = raw; return strings; };

console.log(_taggedTemplateLiteralLoose(["1"], ["1"]));

Как вы можете видеть в приведенном выше примере, после передачи с помощью babel, функция тегирования (console.log) передает значение, возвращаемое следующим переданным кодом es6->5.

_taggedTemplateLiteralLoose (["1"], ["1"]);

Возвращаемое значение этой функции передается в console.log, который затем печатает массив.

Тег с литералом шаблона:

Следующий синтаксис:

function`your template ${foo}`;

Называется теговым литералом шаблона.


Функция, которая вызывается как тег с литералом шаблона, получает свои аргументы следующим образом:

function taggedTemplate(strings, arg1, arg2, arg3, arg4) {
  console.log(strings);
  console.log(arg1, arg2, arg3, arg4);
}

taggedTemplate`a${1}b${2}c${3}`;

  1. Первый аргумент - это массив всех отдельных строковых символов
  2. Оставшийся аргумент соответствует значениям переменных, которые мы получаем посредством интерполяции строк. Обратите внимание, что в примере нет значения для arg4 (потому что есть только 3 раза интерполяция строк) и, таким образом, undefined регистрируется, когда мы пытаемся войти arg4

Используя синтаксис остальных параметров:

Если мы заранее не знаем, сколько раз будет происходить интерполяция строки в строке шаблона, часто полезно использовать синтаксис параметра rest. Этот синтаксис хранит оставшиеся аргументы, которые функция получает в массив. Например:

function taggedTemplate(strings, ...rest) {
  console.log(rest);
}

taggedTemplate `a${1}b${2}c${3}`;
taggedTemplate `a${1}b${2}c${3}d${4}`;

Поздно к вечеринке, но, TBH, ни один из ответов не дает объяснения 50% первоначального вопроса ("почему raw: Array[1]")

1. Почему можно вызывать функцию без скобок, используя обратные кавычки?

console.log`1`

Как указывали другие, это называется шаблоном с тегами (подробнее также здесь).

Используя этот синтаксис, функция получит следующие аргументы:

  • Первый аргумент: массив, содержащий разные части строки, не являющиеся выражениями.
  • Остальные аргументы: каждое из значений, которые интерполируются (т.е. те, которые являются выражениями).

По сути, следующие "почти" эквивалентны:

// Tagged Template
fn`My uncle ${uncleName} is ${uncleAge} years old!`
// function call
fn(["My uncle ", " is ", " years old!"], uncleName, uncleAge);

(см. пункт 2., чтобы понять, почему они не совсем одинаковые)

2. Почему ["1", raw: Array[1]]???

Массив, передаваемый в качестве первого аргумента, содержит свойство raw, который позволяет получить доступ к необработанным строкам по мере их ввода (без обработки управляющих последовательностей).

Пример использования:

let fileName = "asdf";

fn`In the folder C:\Documents\Foo, create a new file ${fileName}`

function fn(a, ...rest) {
  console.log(a); //In the folder C:DocumentsFoo, create a new file
  console.log(a.raw); //In the folder C:\Documents\Foo, create a new file 
}

Что, массив со свойством??????

Да, поскольку массивы JavaScript на самом деле являются объектами, они могут хранить свойства.

Пример:

const arr = [1, 2, 3];
arr.property = "value";
console.log(arr); //[1, 2, 3, property: "value"]

Другие вопросы по тегам