Обратные вызовы вызова функции
Я не уверен, как это объяснить, но когда я бегу
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}`;
- Первый аргумент - это массив всех отдельных строковых символов
- Оставшийся аргумент соответствует значениям переменных, которые мы получаем посредством интерполяции строк. Обратите внимание, что в примере нет значения для
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"]