重学前端 27 # JavaScript的词法

简介: 重学前端 27 # JavaScript的词法

一、JavaScript 的词法(lexical grammar)


ECMAScript 源码文本会被从左到右扫描,并被转换为一系列的输入元素,包括 token、控制符、行终止符、注释和空白符。ECMAScript 定义了一些关键字、字面量以及行尾分号补全的规则。


可以参考MDN文档–词法文法


1.1、分类

  • WhiteSpace 空白字符
  • LineTerminator 换行符
  • Comment 注释
  • Token 词    


IdentifierName 标识符名称:典型案例就是使用的变量名,注意这里关键字也包含在内。

Punctuator 符号:使用的运算符和大括号等符号。

NumericLiteral 数字直接量:就是写的数字。

StringLiteral 字符串直接量:就是用单引号或者双引号引起来的直接量。

Template 字符串模板:用反引号 ` 括起来的直接量。



1.2、特别之处


1、除法和正则表达式冲突问题

JavaScript 不但支持除法运算符//=,还支持用斜杠括起来的正则表达式/.../


解决方案:是定义两组词法,然后靠语法分析传一个标志给词法分析器,让它来决定使用哪一套词法。



2、字符串模板


理论上,${ }内部可以放任何 JavaScript 表达式代码,而这些代码是以 } 结尾的,也就是说,这部分词法不允许出现 } 运算符。

// <!-- 模板语法 -->
`Hello, ${world}`


3、四种词法定义

  • InputElementDiv
  • InputElementRegExp
  • InputElementRegExpOrTemplateTail
  • InputElementTemplateTail





二、空白符号 Whitespace


2.1、空白符号分类


<HT>(或称<TAB>) 是 U+0009,是缩进 TAB 符,字符串中写的 \t 。


<VT>是 U+000B,也就是垂直方向的 TAB 符 \v。


<FF>是 U+000C,Form Feed,分页符,字符串直接量中写作 \f。


<SP>是 U+0020,就是最普通的空格。


<NBSP>是 U+00A0,非断行空格,它是 SP 的一个变体,在文字排版中,可以避免因为空格在此处发生断行,其它方面和普通空格完全一样。


<ZWNBSP>(旧称<BOM>) 是 U+FEFF,这是 ES5 新加入的空白符,是Unicode中的零宽非断行空格,在以 UTF 格式编码的文件中,常常在文件首插入一个额外的 U+FEFF,解析 UTF 文件的程序可以根据 U+FEFF 的表示方法猜测文件采用哪种 UTF 编码方式。这个字符也叫做bit order mark。



2.2、所有的 Unicode 中的空格分类

fcde18c190386f3b02341285c2319455.png




三、换行符 LineTerminator


3.1、四种换行符


   <LF>:是 U+000A,就是最正常换行符,在字符串中的 \n

   <CR>:是 U+000D,这个字符真正意义上的回车,在字符串中是 \r

   <LS>:是 U+2028,是 Unicode 中的行分隔符。

   <PS>:是 U+2029,是 Unicode 中的段落分隔符。


注意:换行符会影响 JavaScript 的两个重要语法特性:自动插入分号no line terminator规则。





四、注释 Comment


// 多行注释
/* MultiLineCommentChars */ 
// 单行注释
// SingleLineCommentChars




五、标识符名称 IdentifierName


IdentifierName可以以美元符$下划线_或者 Unicode 字母开始,除了开始字符以外,还可以使用 Unicode 中的连接标记、数字、以及连接符号。


关键字

await break case catch class const 
continue debugger default delete do else 
export extends finally for function if 
import ininstance of new return super 
switch this throw try typeof 
var void while with yield
// 为了未来使用而保留的关键字
enum
// 在严格模式下还有
implements package protected 
interface private public

NullLiteral(null)和 BooleanLiteral(true false) 也是保留字。

仅当不是保留字的时候,IdentifierName会被解析为Identifier




六、符号 Punctuator


{ ( ) [ ] . ... ; , < > <= >= == != === !== 
+ - * % ** ++ -- << >> >>> & | ^ ! ~ && || 
? : = += -= *= %= **= <<= >>= >>>= &= |= 
^= => / /= }



七、数字直接量 NumericLiteral


JavaScript 规范中规定的数字直接量可以支持四种写法:十进制数、二进制整数、八进制整数和十六进制整数。


1、十进制的 Number 可以带小数,小数点前后部分都可以省略,但是不能同时省略

.01    // 0.01
12.    // 12
12.01  // 12.01


2、12.toString() 为什么会报错?

12.toString()
// Uncaught SyntaxError: Invalid or unexpected token
// 原因: `12.` 会被当做省略了小数点后面部分的数字而看成一个整体,相当于执行了12toString(),所以会报错
// 解决:加入空格让其单独成为一个 token
12 .toString()  // "12"
// 或者加一个.
12..toString()  // "12"


另外科学计数法跟进制就不写了。。。。




八、字符串直接量 StringLiteral


// 双引号
" DoubleStringCharacters "
// 单引号
' SingleStringCharacters '


8.1、单字符转义

即一个反斜杠 \ 后面跟一个字符这种形式。


0a98281928016e478046bc830d991aed.png




九、正则表达式直接量 RegularExpressionLiteral


正则表达式由 Body 和 Flags 两部分组成

/RegularExpressionBody/g



其中 Body 部分至少有一个字符,第一个字符不能是 (因为 / 跟多行注释有词法冲突)。





十、字符串模板 Template


在 JavaScript 词法中,包含 ${ } 的 Template,是被拆开分析的

`a${b}c${d}e`
/*
// 被拆成了五个部分
`a${  //  这个被称为模板头
b     //  普通标识符
}c${  //  被称为模板中段
d     //  普通标识符
}e`   //  被称为模板尾
*/


模板支持添加处理函数的写法,这时模板的各段会被拆开,传递给函数当参数:

function kaimo(){
    console.log(arguments);
}
var temp = "kaimo"
kaimo`hello ${temp} !`
// [["hello ", " !"], "kaimo"]
目录
相关文章
|
25天前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
22天前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
1月前
|
自然语言处理 JavaScript 前端开发
[JS]作用域的“生产者”——词法作用域
本文介绍了JavaScript中的作用域模型与作用域,包括词法作用域和动态作用域的区别,以及全局作用域、函数作用域和块级作用域的特点。通过具体示例详细解析了变量提升、块级作用域中的暂时性死区等问题,并探讨了如何在循环中使用`var`和`let`的不同效果。最后,介绍了两种可以“欺骗”词法作用域的方法:`eval(str)`和`with(obj)`。文章结合了多位博主的总结,帮助读者更快速、便捷地掌握这些知识点。
35 2
[JS]作用域的“生产者”——词法作用域
|
25天前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
38 5
|
23天前
|
缓存 前端开发 JavaScript
JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式
本文深入解析了JavaScript前端路由的实现原理及其在单页应用中的重要性,涵盖前端路由概念、基本原理、常见实现方式(Hash路由和History路由)、优点及挑战,并通过实际案例分析,帮助开发者更好地理解和应用这一关键技术,提升用户体验。
57 1
|
27天前
|
JSON 前端开发 JavaScript
聊聊 Go 语言中的 JSON 序列化与 js 前端交互类型失真问题
在Web开发中,后端与前端的数据交换常使用JSON格式,但JavaScript的数字类型仅能安全处理-2^53到2^53间的整数,超出此范围会导致精度丢失。本文通过Go语言的`encoding/json`包,介绍如何通过将大整数以字符串形式序列化和反序列化,有效解决这一问题,确保前后端数据交换的准确性。
33 4
|
1月前
|
资源调度 前端开发 JavaScript
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第10天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤,包括安装依赖、创建混淆脚本、修改 `package.json` 脚本命令、构建项目并执行混淆,以及在 HTML 文件中引用混淆后的文件。通过这些步骤,可以有效提高代码的安全性。
|
1月前
|
设计模式 前端开发 JavaScript
揭秘!前端大牛们如何巧妙利用JavaScript,打造智能交互体验!
【10月更文挑战第30天】前端开发领域充满了无限可能与创意,JavaScript作为核心语言,凭借强大的功能和灵活性,成为打造智能交互体验的重要工具。本文介绍前端大牛如何利用JavaScript实现平滑滚动、复杂动画、实时数据更新和智能表单验证等效果,展示了JavaScript的多样性和强大能力。
51 4
|
1月前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
1月前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
33 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效