不带括号的函数返回一个奇怪的输出

时间:2018-09-30 01:52:43

标签: javascript

只需询问以了解其工作原理:

function say(something) {
  return something;
}
let name = `Reza`;

console.log(say `My name is`, name, '!');

它返回一个非常奇怪的输出。我认为My name is是数组中的一个字符串,其他所有内容都只是一个字符串(如果我错了,请纠正我)。

我的问题是,这有什么意义?何时使用这样的函数才有意义?

如果有人能告诉我My name is ${name}为何不起作用(name作为空字符串返回),我也很高兴。

PS:我知道可以将函数与括号一起使用,并且可以使用,但这不是我的问题。

6 个答案:

答案 0 :(得分:8)

  

为什么我的名字是$ {name}无效(名称返回为空   字符串)。

这是因为您必须从字符串值数组中提取My name is的值并返回

尝试一下:

function say(something) {
   var str0 = something[0]
   return str0;
}
let name = `Reza`;
console.log(say`My name is${name}`, name, '!');  // My name is Reza !

我们将收到以下内容:

enter image description here

我想指出的是,${name}根本没有任何意义,因为在tag function内,我们什么都没做。

这是在Chrome devtools上运行代码后的结果:

enter image description here

让我们看看如何解释实际发生的情况。那么,您所使用的称为Tagged templates

  

模板文字的更高级形式是带标签的模板。标签允许您使用函数来解析模板文字。标记函数的第一个参数包含一个字符串值数组。

这就是为什么我们在结果中看到array的原因:

例如,如果我们在Chrome devtools上运行以下代码:

function say(something) {
    return something;
}
console.log(say`anything`);

在控制台标签上,我们将收到以下结果:

enter image description here

有关更多信息,您可以在这里阅读:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#Tagged_templates

我们可以看到,根据MDN - Raw strings,奇怪的raw属性是:

  

特殊的raw属性(可用于带标记的模板的第一个函数参数),使您可以在输入原始字符串时访问它们,而无需处理转义序列。

例如:

function tag(strings) {
  console.log(strings.raw[0]);
}

tag`string text line 1 \n string text line 2`;
// logs "string text line 1 \n string text line 2" ,
// including the two characters '\' and 'n'

您正在使用console.log()方法,根据MDN-Console.log(),我们具有其签名:

语法:Console.log()

  

console.log(obj1 [,obj2,...,objN]);

     

console.log(msg [,subst1,...,substN]);

参数

obj1 ... objN

  

要输出的JavaScript对象的列表。的字符串表示形式   这些对象均按列出的顺序附加到一起,   输出。

msg

  

包含零个或多个替换字符串的JavaScript字符串。

subst1 ... substN

  

用于替换替换字符串的JavaScript对象   味精这使您可以进一步控制输出的格式。

在您的情况下,您要将多个参数传递到Console.log()方法中,因此它将按文档中的说明工作:Outputting multiple objects

enter image description here

答案 1 :(得分:2)

say标签缺少模板字符串中占位符的参数:

function shout(parts, name/*<--HERE*/) {
  return `${parts[0]}${name}${parts[1]}!!!`;
}

let name = `Reza`;
console.log(shout `My name is ${name}`);

say从模板字符串中接收数据作为占位符周围的拆分字符串:

[
  "My name is ",
  "!"
] Reza

MDN Documentation看这个例子:

function myTag(strings, personExp, ageExp) {
  var str0 = strings[0]; // "That "
  var str1 = strings[1]; // " is a "

  var ageStr;
  if (ageExp > 99){
    ageStr = 'centenarian';
  } else {
    ageStr = 'youngster';
  }

  // We can even return a string built using a template literal
  return `${str0}${personExp}${str1}${ageStr}`;
}

var person = 'Mike';
var age = 28;
var output = myTag`That ${ person } is a ${ age }`;

答案 2 :(得分:2)

执行My name is ${name}应该可以。这是因为您将My name is作为标签模板文字传递给了say函数,默认情况下,它们将参数作为数组传递

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals

答案 3 :(得分:2)

您标记的模板缺少参数,应该包含一个字符串数组参数作为第一个参数。

 function say(strings, something) { 
    return strings[0] + "Mr. " + something +"!"; 
} 

let name = `Reza`; 
console.log(say `My name is ${name}`);    

答案 4 :(得分:1)

简单点

console.log `Hi there`;

  

为什么我的名字是$ {name}无效(名称返回为空字符串)。

console.log(say `My name is`, name, '!'); /* I don't see `${name}` here */

此外,name从未作为参数传递给say函数!

function say(something) {
  return something;
}
let name = `Reza`;
/* say without () */
console.log(say `My name is ${name} !`);

/* say with () */
console.log(say(`My name is ${name} !`));

let who = 'everyone';
console.log `Hello ${who}`; /* note, no -> () */
console.log(`Hello ${who}`);

答案 5 :(得分:1)

为了回答您的问题,我花了很多时间研究文件。我会尽力简单地解释它。

实际上,我的第一个答案是 文字说明 。但是,我记得W3Schools曾经说过:

  

示例胜过1000个单词。例子通常更容易   比文字解释更了解。

那么,此答案通过澄清“尝试一下”示例补充了所有说明。

Javascript中涉及两个概念:Tagged templatesConsole.log()方法。

我将重新编写您的代码,将它们分为两部分,如下所示:(执行的结果保持不变)。

// part 1
function say(something) {
  return something;
}
let name = `Reza`;
let output = say`My name is`; 
// part 2
console.log(output, name, '!');

让我们看看这两个部分分别与Tagged templatesConsole.log()方法的概念有关。

首先,检查以下示例:

示例1:

function say(something) {
   return something;
}
let output = say`My name is`; 
console.log(output)

运行此示例后,我们将看到一个array包含一个元素,该元素为string:“我的名字是”

这是Tagged templates

的行为

在我们实际研究Tagged templates的工作方式之前,让我们看一下下面的示例:

示例2:

function say(something) {
   return something[0];
}
let output = say`My name is`; 
console.log(output)

运行示例2后,我们将收到一个string:“我的名字是”,而不是示例1的array

那么,如果我想传递一个name怎么办?看到这个:

示例3

function say(something, name) {
   return `${something[0]}${name}`;
}
let name = 'Reza';
let output = say`My name is ${name}`; 
console.log(output)

是的!它按预期工作。那么,如果我想传递两个参数而不是一个参数怎么办?看到这个:

示例4

function say(something, name, age) {
    let str0 = something[0];
    let str1 = something[1];
    let str2 = something[2];
    return `${str0}${name}${str1}${age}${str2}`;
}
let name = 'Reza';
let age = 1000;
let output = say`My name is ${name}, I'm ${age} years old!`; 
console.log(output)

很清楚,对吧?这就是我们使用Tagged templates的方式。

Tagged templates的检查现已完成。让我们看看Console.log()方法的工作原理。

示例5

console.log(`My name is `)

我们都熟悉Console.log()方法的这种用法,并传递了一个参数。那么,如果我想传递多个参数呢?看到这个:

示例6

let name = `Reza`;
console.log(`My name is `, name, '!')

将所有内容合并为一个输出。

那么,现在,让我们回到您的示例:

function say(something) {
  return something;  // the `something` is still an array
}
let name = `Reza`;

console.log(say `My name is`, name, '!');
// the console.log() method will try to combine all these three arguments
// into one single output
// this is why we got the output as an array with a string: "name" and a string: "!"

我们可以这样解决:

示例7

function say(something) {
   return something[0]; 
}
let name = `Reza`;
console.log(say`My name is`, name, '!');

或者这样:

示例8

function say(something, name) {
   return `${something[0]}${name}`; 
}
let name = `Reza`;
console.log(say`My name is ${name} `, '!'); 

但是,让我们看一下这个例子:

示例9

function say(something, name) {
  return `${something[0]}${name}`; 
}
let name = `Reza`;
console.log(say`My name is ${name} `, name, '!');

我们将收到My name is Reza Reza !。我相信,到目前为止,我们所有人都知道为什么得到它。