js 换行符_一文看遍 JS 的所有输入(词法篇)
当你敲下第一行 JavaScript 代码时,我们就已经进入了 JavaScript 的世界了。
在 JavaScript 的世界里,这里的一切都是由我们所敲下的每一个字符所决定,我们一般把这些字符称为我们的基础元素,之后一切的规则和联系都是由此产生。
古人把我们的宇宙万物划分为是由“金”、“木”、“水”、“火”、“土”5 种基础元素组成。那你知道 JavaScript 的世界是由几种基础元素组成的吗?
输入基础元素
同五行划分一样,我们输入 JavaScript 代码中的每个字符,也可以被大体分类。我们把所有的输入统称为inputElement
,宏观上来看,他们可以被分为这 4 大类
可以看到,我们的输入元素基本被分为:
- WhiteSpace:空白字符(其中最常见的就是我们敲的
空格
) - LineTerminator:换行符(我不相信你写代码的时候从来不换行,换行时候用的那个就是了)
- Comment:注释(就是程序员们都想看,但又都不想写的那些东西)
- Token:令牌(Token 其实很难有一个很好的翻译,而且它是一个很泛的概念,之后我会详细的为大家讲解)
WhiteSpace:空白字符
首先来为大家介绍一下我们的空白字符。空白字符是一个常见且神奇的元素,tab
、space
都属于我们常见且常用的空白字符。除了tab
和space
,我们还有其他几种空白字符,看看你有没有见过。
- :纵向 Tab 符
- :换页符
- :NB 空格
- :ZWNB 空格
- :其他 Unicode 空白
这里大家可以看到我们熟悉的身影:<NBSP>
,是否还记得我们的 HTML 的 Entity(Entity 概念也是 HTML 里面鲜为人知的一个概念,之后我会在 HTML 章节细讲)里面也有着
这个东西?
大多数人觉得这只是空格,其实不然!相比于空格space
,nbsp
可多了一个nb
。
好了我知道你脑海里面一定会冒出牛逼空格
这个概念了,不过这个空格确实有它的过人之处。
这个过人之处就要从他的名字中的说起,nb
代表的是no-break
,也就是说他是不会被打破,其实就是相比于正常空格,nbsp
是一个不会换行的空格,不信你可以试一下~
然后还有一个比<NBSP>
名字更长的空格叫做<ZWNBSP>
空格,这个<ZWNBSP>
空格是空格界的黑魔法,他的全称叫做zero-width-no-break-space
也就是零宽空格。你可以通过它制造一些令人匪 huai 夷 yi 所 ren 依 sheng 的代码片段,比如:
小伙伴们发现原来还能这样声明变量a???于是小伙伴们纷纷也在下面打出了这一行代码,于是纷纷得到下面的结果
是不是很神奇,看起来一样的代码却产生了不同的结果!其中的原因就是我们前一段代码在var
与a
之间插入了一个大家看不见的空白字符<ZWNBSP>
。
这个字符无法直接打出,但是我们可以通过 unicode 码uEFEE
进行输入。
这里友情提示:千万不要在工作中使用<ZWNBSP>
,否则你的同事应该会把你打个半死..
LineTerminator:换行符
换行符这里一般就是指我们的回车与换行,还有两个不常见的<PS>
和<LS>
基本可以忽略。
很多人可能会觉得奇怪,会什么一个换行需要两个字符?
我们可以经常看到我们的代码里换行都是rn
这样的写法,这样的原因其实是来自于打字机的换行操作(因为最早的计算机都是类似于打孔机一样的东西)
打字机换行操作是
- 移到行首
- 切换到下一行
于是延续至今,我们的计算机也就出现了
r
移到行首n
切换到下一行
Comment:注释
人人都想看注释,人人都不想写注释。 ——鲁迅
说到注释,这可真是任何语言中都必不可缺的东西了。在我们的 JavaScript 中,他当然也占据着举足轻重的地位。它的基础形式也很简单,主要分为以下两类
//
/* */
剩下的就是大家在里面的肆 bu 意 ke 创 neng 作 xie 了
Token:令牌
接下来就是我们的重头戏:Token。据不完全统计,我们日常 coding 中的 98%输入字符都属于 Token 范畴,其实 Token 范畴很广,目前也没有一个很好的翻译内容,所以我们就先叫它令牌
吧,下面先跟大家大体的介绍一下 Token 概念。
Token 主要由以下几部分组成:
- IdentifierName:标识名称
- Punctuators:符号
- Template:模版
- Literal:直接量
IdentifierName:标识名称
标识名称(IdentifierName)其实很好理解,你写的那些变量名、方法名、类名都属于标识名称。除了你起的五花八门的名称,标识名称还包括 JavaScript 的关键字和保留字,这些名字是不能随便乱用的!总的来说,标识名称包含这些东西
- Keywords:关键字(for,while,var,let,const...)
- Future reserved Keywords:保留字
- Identify:标识(变量名/方法名/类名/... 你自己定义的名称)
如果你想要查询关键字有哪些,可以看JavaScript Keywords,保留字基本上现在好像也就一个enum
所以记住就好啦~
而关于命名规则,你可以查看文档中关于变量命名的规则部分,日常工作中别用乱七八糟的字符就好了
Punctuators:符号
Punctuators 就是我们各种各样的符号,这里会分为三类,分别为:
- Punctuator:
{()[]....;,<><=>===!====!==+-*%**++--<<>>>>>&|^!~ &&||?:=+=-=*=%=**=<<=>>=>>>=&=|=^==>
(我看吐了 - DivPunctuator:
/
,/=
- RightBracePunctuator:
}
我们可以看到在众多符号中/
、/=
、}
特别突出的被单独拎了出来,这是为什么呢?/
是由于在正则和数字计算时有着不同的意义。而/=
和}
也不知道是什么(我猜}
是由于标识代码块的结束范围和模版中的特殊标识)
还有一个特殊的字符 “”,这个字符在JavaScript中是转义符,所以如果你想要打出 “”的话,就要写成""这种形式
所以如何区分符号呢?其实也很简单,不是/
,/=
,}
那基础上就是 Punctuator 了!
Template:模版
模版是一块比较特殊且独立的模块,一行代码概括就是
var username = 'chenmingming'
`Hello ${username}!`
就是它!
Literal:直接量
我们上面说了IdentifierName标识名称
、Punctuators符号
、Template模版
大家是不是觉得还缺点什么?
前面综合起来就好像是var a =
,但是我们没有内容啊!我们平常写的var a = 123
、var b = 'I am chenmingming'
中的123
与I am chenmingming
才是我们 coding 的重要内容,这些内容其实有个名字,叫做Literal(直接量)
让我们穷举一下我们都会有哪些直接量:
var num1 = 123 // 十进制数字
var num2 = 0b101 // 二进制数字
var num3 = 0o177 // 八进制数字
var num4 = 0x1ff // 十六进制数字
var num5 = 1e12 // 科学计数法var str1 = 'abc' // 单引号
var str2 = "abc" // 双引号
var str3 = 'uFEFF' // u转义字符
var str4 = 'r' // 回车
var str5 = 'n' // 换行var boo = true // 布尔类型var reg = /[0-9]/ // 正则var spec = null // Null
我们对以上的直接量进行分类可以分为以下几类:
- NumberLiteral:数字直接量(包含各种进制的数字 + 科学计数法)
- StringLiteral:字符串直接量(单/双引号正常字符 + 转义字符 + 回车换行)
- NullLiteral:null
- BooleanLiteral:布尔类型直接量
- RegExpression:正则表达式
基本上上面这些就是整个 Token 的全部内容了,可能很多同学会疑惑,为什么没有undefined
呢?这里也是一个 JavaScript 的设计失误:把undefined
作为一个变量进行设计,并且还可以赋值!同时也引出了一个最佳实践:在你想使用undefined
的时候使用void 0
进行替代(因为 void 0 总是会返回一个 undefined),这样可以避免undefined
被赋值而导致的异常行为。
u 转义与 Unicode 编码
InputElement 已经全部介绍完了。我们在上面的StringLiteral中发现了这样的一份代码,我们日常也会有看到
var str3 = 'uFEFF' // u转义字符
u 转义还有一个我们很常见的场景:中文字符输入,比如下面场景
var 名字 = 'chenmingming'
// 上下表达的意思一样
var u540du5b57 = 'chenmingming'
这两行代码在其他场景都会正常的运行,然后你会惊喜的发现,我们的中文原来也可以当作变量名啊,那我以后岂不是可以愉快的写下面这种代码?
var 折扣价格 = 折扣计算(商品价格)if (折扣价格 > 100) {console.log('您本次省下了至少100块!')
}
理论上确实是可以的,但是为什么没有人这么写呢?这就要涉及到我们 Unicode 码了。
我们在 JS 中输入的每个字符本质上都是 Unicode 码点。我们的 Unicode 的码点展示出来需要字符集来解析对应的码点,这个字符集有点像我们的字体库,如果字符集(字体库)里面没有我们对应的码点(字体),那么就会解析出一堆乱码,常见的字符集有以下几种
看到没有,英文数字之类的都在 ASCII 字符集范围内所以支持程度也最好,但是你要是用中文,那除了 GB 和 BIG5,其他字符集可看不懂中文,就会乱码了。所以 JavaScript 采用u 这种形式,标识其对应的 unicode 码点。
那么关于获取一个字符的 unicode 编码呢?这里介绍几个 API
String.charCodeAt()
和String.codePointAt()
:获取对应字符的码点Number.toString([进制数])
:将数字转化为 N 进制String.fromCharCode()
:查询码点对应的字符
让我们来动手试试看
"陈".charCodeAt(0) // 38472
"陈".charCodeAt(0).toString(16) // "9648" 所以“陈”也可以通过u9648表示
String.fromCharCode(38472) // "陈"
结尾
看到这里,我们 JavaScript 中的所有基础元素就介绍完毕了,你会发现所有的输入元素都能在其中找到身影。今后你看 JavaScript 的代码至少每个字符你都认识并知道类别了,那么还有什么能阻挡你阅读任何 JavaScript 代码呢?
当然有!那就是 JavaScript 的语法。如果不懂语法就很容易出现我们英语考试时候的尴尬情况:单词我都看得懂,连在一起就不知道是什么意思了所以接下来我们会介绍JavaScript 的语法部分,敬请期待
最后,如果觉得本文对你有帮助,还请点赞喜欢 支持一下我,谢谢啦
js 换行符_一文看遍 JS 的所有输入(词法篇)相关推荐
- python怎么去掉换行符_如何在Python中删除尾部换行符?
如何在Python中删除尾部换行符? 什么是Perl的chomp函数的Python等价物,如果它是换行符,它会删除字符串的最后一个字符? 26个解决方案 1473 votes 尝试方法lstrip() ...
- 【RPA之家转载】RPA行业年度大盘点,一文看遍全球大事件
RPA之家(RPA之家|RPA|RPA新闻|RPA案例|RPA应用|RPA咨询|RPA培训|RPA认证|RPA教程)是中国具有影响力的RPA垂直交流社区,社区汇聚了RPA领域的各类从业人员.其中包括R ...
- js换行符转换html换行
js换行符转换html换行 在标签中加入: dangerouslySetInnerHTML={{ __html: 有换行符的数据?.replace(/[\n]/g, " ")}} ...
- js去掉第一个换行符_通过异步迭代简化Node.js流程
如果我们使用异步迭代,那么使用Node.js流程将更加高效. 异步迭代和异步生成器 异步迭代是用于异步检索数据容器内容的协议,这也意味着当前"任务"可以在检索项目之前被暂停. 异步 ...
- css 识别变量中的换行符_跟我一起全面了解一下CSS变量
什么是css变量? CSS变量,即CSS variable.官方的名称是级联变量的CSS自定义属性,即CSS custom properties for cascading variables.类似于 ...
- angular 字符串转换成数字_一文看懂Python列表、元组和字符串操作
好文推荐,转自CSDN,原作星辰StarDust,感觉写的比自己清晰-大江狗荐语. 序列 序列是具有索引和切片能力的集合. 列表.元组和字符串具有通过索引访问某个具体的值,或通过切片返回一段切片的能力 ...
- mac txt 换行符_推荐两款免费的网页代码编辑器(Win和Mac系统)
大家好,我们在修改PHP代码的时候,尽量不要使用系统自带的文本编辑器,更不能使用Word之类的字处理软件,应该是用"代码编辑器" .下面这个视频教程是我之前做的,没在WordPre ...
- excel宏转txt替换强制换行符_三个步骤学会用EXCEL批量导入anki题库
Anki真的是个好用到不想推荐给朋友的软件,本人最近准备刷个新题库,找了一上午找不到原来教我EXCEL导入anki的网页,为了防止我自己过段时间又忘了应该怎么导入,我写了这个教程,写都写了,就顺手发出 ...
- linux 换行符_「linux」libevent demo详细分析(对比epoll)
libevent默认情况下是单线程,每个线程有且仅有一个event_base,对应一个struct event_base结构体,以及赋予其上的事件管理器,用来安排托管给它的一系列的事件. 当有一个事件 ...
最新文章
- JS组件系列——开源免费图表组件:Chart.js
- 手动建立规则方式创建stream环境
- ios10前台收到推送_iOS 13 beta 2 推送 | iOS 13 热门疑问解答
- oracle clob截取_Oracle数据库设计规范建议
- java 双重检查锁 有序_Java中的双重检查锁(double checked locking)
- iPhone 13系列电池容量最高4350mAh 较iPhone 12提升近20%
- vue项目启动出现cannot GET /服务错误
- ipad降级系统无法接通服务器,红雪0.9.14b2基带降级图文教程
- 开启memcached日志
- 吃鸡 python开发_ 冲顶大会等游戏答题神器,提供答题辅助决策 ,帮助顺利吃鸡...
- Filter过滤器及其作用
- Excel笔记(4)常用函数21-34
- MIUI12 安卓12刷面具root 理论适合所有小米机型和系统版本 小米10实测 小米11实测
- Python 实现简单虚拟跑步机计算消耗的能量
- cocos creator中FBX文件不可用显示asset invalid
- 个人常用的sql脚本语句
- 大b和小b的区别是什么
- 尚硅谷JavaWeb_2020idea_王振国_学习笔记
- ubuntu 磁盘管理工具 ---- GParted 图形化分区工具
- 华盈IP PBX UC1910统一网关