【问题标题】:Why do array functions work like tagged template literals and what can I do with it?为什么数组函数像标记的模板文字一样工作,我能用它做什么?
【发布时间】:2020-07-01 04:24:46
【问题描述】:

就在最近,我发现这是可行的:

const str = "foo bar";
const arr = str.split` `; // <- no parens
console.log(arr);
// -> ["foo", "bar"]

看起来split 原型是一个标记的模板文字。我还看到它与其他数组函数一起使用,例如 indexOf

实施此行为是否有特定原因? 我可以用它做一些我以前做不到的事情吗?或者我可以用更简单的方式解决一些任务吗?

似乎已经为实现付出了一些努力,而我能想到的每个用例都会使事情变得过于复杂。在我看来,让它成为可能是浪费时间。还是零成本?如果是:如何?

【问题讨论】:

  • 模板字面量调用语法只是另一种函数调用机制。你可以这样调用 any 函数。
  • 您应该查看标记模板字面量如何调用标记 (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…) 并将其与 split 的预期值进行比较。不确定您是通过“实现此行为的特定原因”还是您希望以这种方式使用标记模板文字的原因来引用语言本身。

标签: javascript ecmascript-6 template-literals language-specifications


【解决方案1】:

.split 方法没有什么特别之处,这就是标记模板文字的工作方式。您可以使用 any 函数标记模板文字,并且它将作为其第一个参数给出插值块之外的模板字符串部分。在这种情况下,数组 [" "] 将用作 .split 的第一个参数(之后将 [" "] 转换为字符串:" ")。

【讨论】:

    【解决方案2】:

    您可以将任何函数用作模板标签。

    模板标签函数接收以下参数:

    1. 静态字符串部分数组
    2. 无穷大。 替换值

    因此,您的电话将展开为:

    const arr = str.split([' ']);
    

    String#split() 期望它的第一个参数是字符串或正则表达式。数组不是这两者,所以.split() 通过调用其.toString() 方法将其转换为字符串。

    Array#toString() 返回以逗号分隔的数组元素。如果是单个元素,则返回转换为字符串的元素。

    由于' '已经是一个字符串,所以它被返回,并被.split()用来分割输入字符串。


    虽然在某些情况下可以这样工作,但不鼓励这种用法(将函数用作并非为此而设计的标记函数),因为它不可读,性能较低(创建额外的数组等)并保存只有 2 个字符(` ` 而不是 (' ')),但是,它被一些压缩器和混淆器使用。

    【讨论】:

      【解决方案3】:

      String.prototype.split 实际上并不是为使用标记的模板文字而设计的。

      当你用标记模板调用split时,传递给函数的第一个参数是模板中的字符串数组,所以

      str.split` `;
      

      等价于

      str.split([" "]);
      

      。该数组只有一个字符串,并且没有更多参数,因为模板文字中没有占位符(${})。

      规范说split 方法首先将第一个参数转换为字符串,然后使用它,所以

      str.split([" "]);
      

      等价于

      str.split(" ");
      

      .

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-18
        • 2019-11-16
        • 1970-01-01
        • 2015-09-04
        相关资源
        最近更新 更多