Eloquent JavaScript笔记1: Values, Types and Operators

Eloquent JavaScript 是一本非常基础且通俗易懂的 JS 入门书,适合小白用来入门。但同时它的知识又很全面,阅读的时候会时不时发现原来有很多知识点自己在以前的学习过程中遗漏了,正好查漏补缺。

顺便说个题外话,这本书我下的电子版,网上有 Free E-Book。之前用 PDF Expert 看,觉得还挺方便的,可以画画线,再把划线的内容导出来整理。谁料后来我竟意外地遇见了 MarginNote 3 这一学习神器,它能一遍阅读一边标记,标记出来的内容又会自动罗列成列表,同时生成思维导图,简直不要太智能。所以这次的笔记内容,就是我对照 MarginNote 的思维导图来整理的。真心安利,良心产品,每一个用心学习的盆友都值得拥有!

计算机里的“内容”都是用 Bit(比特)来存储的。比特就是一种二元的事物,说白了就是我们常说的电脑都是0 和 1。

Value 值

计算机中有大量的0 和 1,在操作它们的时候,为了不搞混,我们需要把它们拆分成一块一块的信息。在 JS 的语境中,这些块就叫 **values (值)**。

这些值又分为不同的类别。


Numbers 数值

表示数字的值就是数值

上面提到,这些块的储存就是值,对于数值来说,它的储存方式比较特别,会有单独的一个比特用来存储负的数值的负号。更麻烦一些的是,数值还包括了小数,有一些比特会专门用来保存小数点所在的位置

对于数值的计算来说,整数的计算(小于 9 万亿的整数)一般都是准确的,但是小数的计算则不是。

数值的计算方法

常见操作符就是我们从小学过的+-*/,在没有括号的情况下,它们的操作顺序就是顺着来。(嗯,就是小学数学

比小学更高深一点的是%,叫做remainder operation,取余,就是求余数。

特殊数值

JS 里有 3 个特别的数值,它们是数,但它们又不能像数一样加减乘除。它们分别是 **Infinity 正无穷、-Infinity负无穷和NaN**。

Infinity正无穷减 1 还是正无穷,总之,不要依赖无穷们来做计算,它们不会得到你希望的结果。

NaN的意思是“not a number”,翻译过来就是“不是个数”,但事实上它又是数值这一类。总之是个很任性的值。


Strings 字符串

字符串用来表示文本

字符串可以用**单引号‘’,双引号“”,反引号``来标识。当字符串中有 \ 字符时,标识 \ 后面的字符是一个特殊字符,需要转义 (escaping the character)**。

字符串统一需要用一系列的比特来存储。JS 存储字符串的标识是 Unicode。简单来说,就是每一个字符都被赋予了一个数字,一个字符串可以用一连串的数字来表示。

字符串不可以做减、乘、除一类的运算,但是它可以用+来“计算”。当你将一个字符串“加上”另一个字符串时,就是将他们拼接在了一起

前面提到不同的引号都可以用来表示字符串,反引号包裹的字符串叫做模板字符串 template literals。模板字符串不仅可以转行,还可以嵌入其他值。当你在模板字符串中使用 ${} 时,${} 中的值会被计算出来,并转换成字符串。

1
`half of 100 is ${100 / 2}` => 'half of 100 is 50'

Unary Operators 一元运算

并非所有的运算符都是符号,有些也是单词的模样。其中一个例子是**typeof,它的作用是以字符串的形式返回一个值的类型**。

1
2
console.log(typeof 4.5)  //number
console.log(typeof "x") //string

大部分运算符被用来操作两个值,但typeof只操作一个值。需要依赖两个值返回结果的运算叫做二元运算符binary operators只需要一个值的叫做**一元运算符unary operators**。减号既可以用作二元运算符(即做减法),也可以用作一元运算符(表示负号)。


Boolean Values 布尔值

布尔值只有两个值,真true和假false

Comparison 比较

><就是大于和小于号,他们是二元运算符。字符串也可以用它们比较。字符串比较的方法简单来说就是按照字母顺序,但是不完全是字母顺序,还包括其他规则,比如大写字母总是“小于”小写字母。非字母的字符,比如!-之类的符合也可以比较。

其他的类似操作符还包括>=<===(相等)、!=(不等)。

JS 中只有一个值,它不等于它自己,就是NaNNaN用来表示所有不符合规则的运算结果,所以它当然也没法等于其他不规则的运算结果。

Logical Operators 逻辑运算符

JS支持三种逻辑运算符:and, or, not

&&表示and,就是和。它是一个二元运算符,只有在它左右两边的值都为真时,它的结果才为真。

||表示or,就是或。它左右两边有一个为真时,它的值就为真。

!表示not,就是非。它是一个一元运算符,当赋予它的值是真时,它的结果就为假,赋予它的值为假时,它的结果就为真。

运算符的优先级是:||优先级最低,&&其次,>, ==之类的再次,然后是其余的运算符。

还有一个三元运算符,它的写法是问号加冒号。

1
console.log(true ? 1 : 2)  //1

它是一个条件式运算符,问号前面是条件,条件为真时返回冒号前面的结果,条件为假时,返回冒号后面的结果。


Empty Values 空值

有两个用来表示没有值的值,它们是nullundefined。它们就是它们本身的值,就是没有值(这句真是别扭,我直接放英文好了They are themselves values, but they carry no information)。

undefinednull之间的区别是什么呢?em…这两个值是 JS 设计中的一个意外,大部分时候它们都没有区别。


Automatic Type Conversion 类型转换

当运算符被赋予错误类型的值时,JS 会悄默默地把值转换成适合的类型,虽然有时候这并不是我们期望的,这个叫做type coercion强制类型转换。

大部分情况下,这条规则会将其中一个运算值转换成和另一个值相同的类型。但是,当运算符的一侧是undefinednull时,只有当运算符的两边都是undefined或者null,运算结果才会是true

如果你不希望发生强制类型转换,可以使用===!==运算符。===表示完全等于,即值和类型都一样。

Short-Circuiting of Logical Operators 逻辑运算符的较短路径

&&||两个运算符会将符号左侧的值转换成布尔值,再决定接下来如何运算。

对于||运算符来说,当左侧为真时,它就会返回右侧的结果。我们可以利用这个规则来设定默认值。

1
2
console.log(null || 'user')  //user
console.log('Agnes' || 'user') //Agnes

&&的运算逻辑也类似,但略有不同。当左侧的值为假时,它就会返回这个值,如果左侧为真,就返回右侧的值。

所谓较短路径就是,只有当必要时,它们才会计算右边的值,如果左边的值能够确定且最终结果就是左边的值,它们不会在意右边的值是什么。