首页 > 其他分享 >关于模板字面量,我有点好奇它的内部结构

关于模板字面量,我有点好奇它的内部结构

时间:2023-06-11 12:32:15浏览次数:53  
标签:字面 内部结构 let 字符串 line strings 模板

前言

最近翻看源码的时候,发现一些有趣的 JS 的知识点,基于日常的开发经验,我做了一些联想和对比。整个过程充满了乐趣。

于是我想,是不是可以延续这种创意带来的学习的乐趣。

带的富含创造力夜晚的 buff,确实让我拥有了不错的灵感。这些灵感像繁星一样闪耀着我的夜里,留下一行文字:

关于模版字面量,好奇它的内部结构吗?

文章速读

阅读文章,可以有以下收获:

关于模板字面量,我有点好奇它的内部结构_源码

模板字面量的内部结构

编程欢乐小剧场

这天某正在欢乐的敲代码,过程流畅丝滑,不带一丝一毫的停顿。

某再敲下一行代码之后,停了下来,并转身问了一个问题。

某:你认真思考过一个问题吗?

一:我俩为什么相识?不用思考,肯定是考验我的,俗话说,天将降大任于......

某:停,停,嘴皮子太溜了。我是说,你看这行代码。

一:还能写的这么复杂呢?

某:都说模板字面量是一种可执行结构。它的内部结构是什么样的?

一:这个我还真没想过,不过我们可以打印一下。

某:键盘递上

模板字面量的内部结构怎么打印?

我受 MDN 官网的启发,反复试验了几次,我感觉我是弄明白了。跟大家演示一下整个过程。

展开参数

第一种,直截了当的展开参数:

let num1 = 1;
let num2 = 2;

function tag(...strings) {
  console.log(strings);
}

tag`string text line ${num1} and line ${num2}`;

打印结果

// > [ [ 'string text line ', ' and line ', '' ], 1, 2 ]

借助关于 String.raw() 的理解,大致明白了这个结构。

这个结构主要包括两个部分:原始字符串和其他字符串。

  • 原始字符串会被放在第一个参数中,这个参数类型是数组,而这个参数存在一个特殊的属性 raw ,可以通过它来直接访问模板字符串的原始字符串,而不经过特殊字符的替换。
  • 其他字符串参数在原始字符串之后。

需要注意的一点是原始字符串是包含转义字符,而其他字符串包含占位符等,比如代码中的 ${num} 。

转义字符

当模版字符串里面包含像 \n 这类的转义字符,\n 不会被特殊处理,它会被放入原始字符串之中。

tag`string text line ${num1} \n line ${num2}`;

打印结果

// > [ [ 'string text line ', ' \n line ', '' ], 1, 2 ]

raw 属性

raw 属性可以获取一个模板字符串的原始字符串。

let num1 = 1;
let num2 = 2;

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

tag`string text line ${num1} and line ${num2}`;

打印结果

// > [ 'string text line ', ' and line ', '' ]

听说模板字面量还支持复杂的写法?

日常开发

在日常开发中,经常在如下的场景中使用模版字面量:

// 三元表达式
type === 'admin' ? `${name}` : `${userName}`;

// 带参数的跳转路径
history.push(`/detail?id=${id}`)

// 简单的求和表达式
var a = 5;
var b = 10;
console.log(`sum: ${a + b}`);

复杂写法

插入循环

下面的代码通过数组循环获取属性 num 的值拼接成字符串,连接左右的字符串'['和']',最终展示为数组的形式。

let example = [{ num: 1 }, { num: 2 }, { num: 3 }];
let str = `数组的另一种展示方式:[${example.map(({ num }) => num).join(', ')}]`;

console.log(str);

打印结果

// > 数组的另一种展示方式:[1, 2, 3]

我从 axios 源码中看到了上面例子中的写法,恍然大悟,模版字面量原来还可以这样玩。

补充模板字面量的知识点

标签函数

前面探索模板字面量的内部结构中的举例,其实还可以将 tag 函数的入参换成下面这种:

let num1 = 1;
let num2 = 2;

function tag(strings, numExp1, numExp2) {
  const str0 = strings[0];
  const str1 = strings[1];
  const str2 = strings[2];
  return `${str0}${numExp1}${str1}${numExp2}${str2}`;
}

let output = tag`string text line ${num1} and line ${num2}.`;
console.log(output);

打印结果

// > string text line 1 and line 2.
标签函数的定义

有了前面的基础,标签函数也好理解了:

接受了一个模板字符串作为实参的函数。

标签函数的参数

再回到 tag 函数参数,这三个参数也比较好理解,前面的过模板字面量的内部结构中有过介绍。这里再详细介绍一下:

strings:字符串数组,里面包含模板字符串中全部的原始字符串。

num1:第一个占位符的值。

num2:第二个占位符的值。

标签函数的参数转换

熟悉模板字面量的内部结构的另一个帮助,我们可以继续tag 函数参数的转换实验,上面的代码等同于下面的代码:

let num = 1;
let num2 = 2;

function tag(strings, ...rest) {
  const str0 = strings[0];
  const str1 = strings[1];
  const str2 = strings[2];
  const numExp1 = rest[0];
  const numExp2 = rest[1];
  return `${str0}${numExp1}${str1}${numExp2}${str2}`;
}

let output = tag`string text line ${num} and line ${num2}.`;
console.log(output);

小结

  1. 模版字面量的内部结构包括原始字符串和其他字符串两个部分。
  2. 原始字符串中包含转义字符,其他字符串主要包括占位符等。
  3. 模版字面量自带的 raw 属性可以获取一个模板字符串的原始字符串。
  4. 模版字面量的复杂写法,某些情况下比较灵活的得到想要的结果。
  5. 标签参数是指接受一个模板字符串作为实参的函数。

总结

关于模版字面量的内部结构,摸索的过程还是很有趣的。虽然从前面的篇幅中看着很简单,但是其实我反复实验了多次,并且借助 String.raw() 的知识点,才很好的理解了输出中的结果。

虽然事情没有看上去的简单,但是结果还是很令人欣慰的。

今天还有一个不错的收获,原来模版字面量里还可以插入循环,一扇新的窗户打开了。

彩蛋

有时候觉得实现方式挺有趣的,但是又说不上哪里有趣?

花时间花心思设计出一个不错的功能,实现思路有趣,代码逻辑清晰,功能本身也丰富多彩。但是等到跟大家安利的时候,却不知道从何说起,甚至连怎么用都表达的不够清晰。

不善表达?

1.理清条理。讲之前,不妨先把功能的是什么、怎么用、核心实现列出来。提前做好准备,等到真正做分享的时候,能清楚明白的表达自己是想法。

2.言必有中。有时候分享的内容不在于文字的数量,而在于能说到点子上。不然,听众听了半小时,还云里雾里,不知道分享的功能到底是什么。

3.扩宽技术词汇量。这是很关键的一点,有时候讲解的内容,远没有功能本身精彩。,比起很直白的说这么写功能就好使,介绍用了什么设计模式、包含哪些技术概念,可以更有吸引力。

怯场?

心中总有腹稿万千,等到台上看着大家期待的眼神,准备好的开场白,瞬间跑了一半。磕磕巴巴的讲完,有点懊恼没有表达好。

这种情况,我给的两个建议是自信+准备充足。

首先,自信不单单指当时的状态,还有对分享的内容。

然后,准备充足是指,演讲稿要简要而全面。我一般会准备PPT,内容不会特别多,但是全。这样腹稿忘了的时候,照着PPT能继续下去。

最后,分享前,尽量自己先做几次完整的分享练习,看能否连贯的将分享内容讲出来。

总结时刻

练习是亘古不变的良策。

如果觉得文章还不错,就 点赞 + 收藏 一波,持续产出技术分享。

标签:字面,内部结构,let,字符串,line,strings,模板
From: https://blog.51cto.com/u_15838863/6457437

相关文章

  • Vue入门实战05-模板语法
    Vue使用一种基于HTML的模板语法,声明式将其组件实例的数据绑定到DOM。所有Vue模板都是语法层合法的HTML,可被符合规范的浏览器和HTML解析器解析。底层机制中,Vue会将模板编译成高度优化的JavaScript代码。结合响应式系统,当应用状态变更时,Vue能够智能地推导出需要重新渲染的......
  • Android 自定义View模板代码记录
    原文地址:Android自定义View模板代码记录-Stars-One的杂货小窝每次写自定义View,需要重写3个构造方法,如果使用AndroidStudio直接创建,会导致View代码过多,于是稍微删了点多余代码,搞一份简洁的模板代码供自己使用模版代码importandroid.content.Contextimportandroid.util.......
  • 大数模板mod int
    大数模板,存档一下template<llM=ll(1e9+7)>structmod_int{llx;mod_int(llx=0):x((x%M+M)%M){}mod_intoperator+(mod_intb)const{returnmod_int((x+b.x)%M);}mod_intoperator-(mod_intb)const{returnmod_int((x-b.x......
  • 模板元编程之函数模板(一)
    一、概述函数模板提供了一种函数行为,该函数行为可以用多种不同的类型进行调用,换句话说函数模板代表一个函数家族,它的表示看起来和普通的函数很相似,唯一的区别就是有些函数元素是未确定的,这些元素将在使用时被参数化。下面是一个返回两个值中最大者的函数模板template<typenam......
  • 典型用户模板分析
    用户一:名字:zz性别、年龄:男,19职业:大二学生收入:无知识层次和能力:大学本科,精通手机电脑各种功能生活/工作情况:以父母给的生活费为生动机,目的,困难:想垃圾分类正确,不会垃圾分类。用户偏好:喜欢对垃圾进行分类用户比例:80%典型场景:有强烈强迫症1.背景:(1)典型用户大......
  • Luogu P1939 【模板】矩阵加速(数列)
    【模板】矩阵加速(数列)题目描述已知一个数列\(a\),它满足:\[a_x=\begin{cases}1&x\in\{1,2,3\}\\a_{x-1}+a_{x-3}&x\geq4\end{cases}\]求\(a\)数列的第\(n\)项对\(10^9+7\)取余的值。输入格式第一行一个整数\(T\),表示询问个数。以下\(T\)行,每行一个正......
  • Luogu P3390 【模板】矩阵快速幂
    【模板】矩阵快速幂题目背景一个\(m\timesn\)的矩阵是一个由\(m\)行\(n\)列元素排列成的矩形阵列。即形如\[A=\begin{bmatrix}a_{11}&a_{12}&\cdots&a_{1n}\\a_{21}&a_{22}&\cdots&a_{2n}\\\vdots&\vdots&\ddots&......
  • Luogu B2105 矩阵乘法(模板)
    矩阵乘法题目描述计算两个矩阵的乘法。\(n\timesm\)阶的矩阵\(A\)乘以\(m\timesk\)阶的矩阵\(B\)得到的矩阵\(C\)是\(n\timesk\)阶的,且\(C[i][j]=A[i][0]\timesB[0][j]+A[i][1]\timesB[1][j]+\)……\(+A[i][m-1]\timesB[m-1][j](C[i][j]\)表示\(C\)......
  • MDT部署Windows系列 (十二): 进阶篇—制作完美的Win10 22H2系统镜像模板之移除Windows
    前言由于工作等原因(借口),距离发布上一篇MDT系列的文章已经过去一年::twemoji:sweat::上一章我记录了基于MDT如何使用一个Task即可实现制作Windows基础wim镜像+DIY基础软件+捕捉镜像。传送门有好多同学一直咨询在制作捕捉镜像的时候遇到的常见的2个问题:如何彻底的移除掉Windows10中......
  • golang实现设计模式之模板模式-优缺点,适用场景
    模板模式是一种行为型设计模式,其定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。特点1.算法结构已确定。2.具体实现交由子类实现。结构1.抽象类(AbstractClass)。算法步骤可以被声明为抽......