1.1 概述与定义
- JavaScript 类型:原始类型和对象类型。
- 原始类型:数值、字符串、布尔值。
- 对象类型:在 JavaScript 中,任何不是 数值、字符串、布尔值、符号、null 和 undefined 的值都是对象。
- JavaScript 的对象类型是可修改的(mutable),而它的原始类型是不可修改的(immutable)。
- JavaScript 程序可以修改 对象属性 和 数组元素 的值。
- 数值、布尔值、符号、null 和 undefined 是不可修改的。
1.2.1 整数字面量
基数为 10 的整数可以直接写成数字序列。如:0,3,20
除了基数为 10 的整数字面量外,JavaScript 也支持其他进制值。
十六进制:以 0x 或 0X 开头,后跟一个十六进制数字字符串。十六进制数字是数字 0 到 9 和字母 a(或 A)到 f(或 F),a 到 f 表示 10 到 15。例如: 0xff:255(15 * 16 ^ 1 + 15 * 16 ^ 0 = 255)
二进制:以 0b 开头。例如:0b10101 =>(21)
八进制:以 0o 开头。例如:0o377 => (255)
1.2.2 浮点字面量
- 浮点字面量可以包含小数点。例如:1.1、123.4。
- 浮点字面量也可以使用指数记数法表示,即在实数值后面跟字母 e (或 E),跟一个可选的 + 或 -,再跟一个整数指数。这种记数法表示的是实数值乘以 10 的指数次幂。 例如:6.1E2 => (610)
1.2.3 JavaScript 中的算术
- 表示加法的 + ,表示减法的 - ,表示乘法的 *,表示除法的 /,表示取余的 %,表示取幂的 **。
- 除了上面的基本运算符外,JavaScript 还通过 Math 对象的属性提供了一组函数和常量,以支持更复杂的数学运算。
Math.pow(2,3) // => 8:2 的 3 次方 Math.round(0.6) // => 1.0:取舍到最近的整数 Math.ceil(0.6) // => 1.0:`向上`舍入到一个整数 Math.floor(0.6) // => 0.0:`向下`舍入到一个整数 Math.abs(-5) // => 5:绝对值 Math.max(x,y,z) // => 返回最大的参数 Math.min(x,y,z) // => 返回最小的参数 Math.random() // => 伪随机数 x,其中 `0 ≤ x < 1` Math.PI // => 3.1415926... :圆周率 Math.E // => e: 自然对数的底数 Math.sqrt(4) // => 2:4 的 `平方根` Math.pow(8, 1/3) // =>2:8的 `立方根` Math.sin() // => 三角函数:还有 Math.cos、Math.atan 等 Math.log(10) // => 10 的自然对数 Math.log(100) / Math.LN10 // => 2: 以 10 为 底 100 的对数 Math.exp(3) // => 20.085536923187668:Math.E的立方
ES6 新增函数:
Math.cbrt(27) // => 3:立方根 Math.hypot(3, 4) // => 5:所有参数平方和的平方根 Math.log10(100) // => 2:以 10 为底的对数 Math.log2(1024) // => 10:以 2 为底的对数
JavaScript 中算术在遇到上溢出、下溢出或被零除时不会发生错误。
上溢出时,结果是一个特殊的无穷值 Infinity,当某个负数的绝对值超过最大可表示数值时,结果为 -Infinity。
下溢出发生在数值操作的结果比最小可表示数值更接近 0 的情况下。此时 JavaScript 返回 0。
被零除在 JavaScript 中不是错误,只会简单的返回无穷或负无穷。不过 0 除以 0 是没有意义的,该操作返回的结果是一个特殊的 “非数值” (NaN)。无穷除无穷、负数平凡根或者无法转换为数值的非数值作为算术运算符的操作数,结果都是 NaN。
ES6 定义的 Number 属性:
Number.parseInt() // 同全局 parseInt() 函数 Number.parseFloat() // 同全局 parseFloat() 函数 Number.isNaN(x) // 判断 x 是不是 NaN Number.isFinite(x) // 判断 x 是数值还是无穷 Number.isInteger(x) // 判断 x 是不是整数
非数值在 JavaScript 中与任何值比较都不相等,也不等于自己。
这意味着不能通过 x === NaN 来确定某个变量 x 的值是 NaN。相反,此时必须写成 x != x 或 Number.isNaN(x)。这两个表达式当且仅当 x 与 全局常量 NaN 具有相同值时才返回 true。
负零值也有点不同寻常。它与正零值相等。
0 === -0 // true
1.2.4 二进制浮点数与舍入错误
- 在通过 JavaScript 操作实数时,数值表示的经常是实际数值的近似值。
这不是 JavaScript 独有的问题,而是所有使用二进制浮点数的编程语言的共同问题。
1.2.5 通过 BigInt 表示任意精度整数
BigInt 这种数值类型的值是整数。
添加这个类型,主要是为了表示 64 位整数,这对于兼容很多其他语言和 API 是必需的。
BigInt 字面量写作一串数字后跟小写字母 n。默认情况下,基数是 10,但也可以通过前缀 0b、0o 和 0x 来表示 二进制、八进制和十六进制BigInt。
1234n // => 一个不太大的 BigInt 字面量 0b11n // => 3n 0xfn // => 15n
- 可以用 BigInt() 函数把常规 JavaScript 数值或字符串转换为 BigInt 值
BigInt(5) // => 5n BigInt(Number.MAX_SAFE_INTEGER) // => 9007199254740991n
- BigInt 可以表示超大值,因此它比常规数值更通用。但 BigInt 只能表示整数,这样看常规 JavaScript 数值类型反而更通用。JavaScript 只是简单的 不允许 在使用 算术操作符时 混用这两种类型的操作数。
- 比较运算符允许混合操作数类型。
1 < 2n // true 2 > 1n // true 0 == 0n // true 0 === 0n // false
位操作符通常可以用于 BigInt 操作数。但 Math 对象的任何函数都不接收 BigInt 操作数。
位操作符:与、或、异或…
1.2.6 日期和时间
JavaScript为表示和操作与日期及时间相关的数据而定义了简单的 Date 类。
JavaScript 的 Date 是对象,但也有数值表示形式,即自 1970 年 1 月 1 日 起至今毫秒数,也叫时间戳。
let timestamp = Date.now() // 1649928295586 【当前时间的时间戳】 let now = new Date() // Thu Apr 14 2022 17:24:55 GMT+0800 (中国标准时间) 【当前时间的日期对象】 let ms = now.getTime() // 1649928295586 【转换为毫秒时间戳】 let iso = now.toISOString() // 2022-04-14T09:24:55.586Z 【转换为标准格式的字符串】
1.3 文本
JavaScript 中表示文本的类型是 String,即字符串。
1.3.1 字符串字面量
可以把字符串放到 单引号''、双引号""、或 反引号`` 中。
双引号字符和反引号可以出现在由单引号定界的字符串中,同理由双引号和反引号定界的字符串里也可以包含另外两种引号。
'' // 空字符串 '3.14' "JavaScript" 'name = "Mike"' `'She is a good girl'`
- 如果需要在单引号或双引号字符串中包含换行符,需要使用字符序列
\n
。
const a = 'two\nlines' //输出在两行 const b = 'one\long\line' //输出在同一行 console.log(a) console.log(b)
- ES6 的反引号语法 支持 跨行字符串。
const a = `Hello World!` console.log(a)
1.3.2 字符串字面量中的转义序列
- 反斜杠的作用:它与后面的字符组合在一起,可以在字符串中表示一个无法直接表示的字符。
- \' 表示单引号(或撇号)字符
const a = 'You\'re beautiful!' console.log(a) //You're beautiful!
- JavaScript 转义序列
\b //退格符 \n //换行符 \t //水平制表符 \v //垂直制表符 \f //进纸符 \r //回车符 \" //双引号 \' //单引号 \\ //反斜杠 \xnn //由2位十六进制数字 nn 指定的 Unicode 字符 \unnnn //由4位十六进制数字 nnnn 指定的 Unicode 字符 \u{n} //由码点n指定的 Unicode 字符,其中 n 是介于0和10FFFF之间的1到6位十六进制数字(ES6)
- 如果字符 \ 位于上表之外的字符前面,则这个反斜杠会被忽略。
\# //输出 #
1.3.3 使用字符串
- 拼接字符串是JavaScript的一个内置特性。
- JavaScript 操作字符串的 API:
let s = 'Hello, world' //取得字符串的一部分 console.log(s.substring(1,4)) //'ell': 第2~4个字符 (前闭后开) console.log(s.slice(1,4)) //同上 console.log(s.slice(-3)) //'rld': 最后3个字符 //搜索字符串 console.log(s.indexOf('l')) //2: 第一个字母 l 的位置 console.log(s.indexOf('l', 3)) //3: 位置3后面第一个 l 的位置 console.log(s.indexOf('zz')) //-1: s并不包含子串 'zz' console.log(s.lastIndexOf('l')) //10: 最后一个字母 l 的位置 //ES6 及之后版本中的布尔值搜索函数 console.log(s.startsWith('Hell')) //true: 字符串是以这些字符开头的 console.log(s.endsWith('!')) //false: s不是以它结尾的 console.log(s.includes('or')) //true: s包含子串 'or' //创建字符串的修改版本 console.log(s.replace('llo', 'ya')) //'Heya, world' console.log(s.toLowerCase()) //hello, world: 转为小写 console.log(s.toUpperCase()) //HELLO, WORLD: 转为大写 console.log(s.normalize()) //Hello, world: Unicode NFC 归一化:ES6新增 console.log(s.normalize('NFD')) //Hello, world: NFD 归一化 还有 'NFKC' 和 'NFKD' //访问字符串中的个别(16位值)字符 console.log(s.charAt(0)) //'H': 第一个字符 console.log(s.charAt(s.length-1)) //'d': 最后一个字符 console.log(s.charCodeAt(0)) //72: 指定位置的16位数值 console.log(s.codePointAt(0)) //72: ES6 适用于码点大于 16 位的情形 //ES2017新增的字符串填充函数 console.log('x'.padStart(3)) //' x': 在左侧添加空格 让字符串长度变为3 console.log('x'.padEnd(3)) //'x ': 在右侧添加空格 让字符串长度变为3 console.log('x'.padStart(3, '*')) //'**x': 在左侧添加星号 让字符串长度变为3 console.log('x'.padEnd(3, '-')) //'x--': 在右侧添加破折号 让字符串长度变为3 //删除空格函数 trim() 是ES5就有的 其他是ES2019新增的 console.log(' test '.trim()) //'test': 删除开头和末尾的空格 console.log(' test '.trimStart()) //'test ': 删除左侧空格 也叫 trimLeft console.log(' test '.trimEnd()) //'test ': 删除左侧空格 也叫 trimRight //未分类字符串方法 console.log(s.concat('!')) //Hello, world!: 可以用 + 操作符代替 console.log('<>'.repeat(5)) //<><><><><>: 拼接n次 ES6 新增
- JavaScript 中的字符串是 不可修改的。像 replace() 和 toUpperCase() 这样的方法都返回新字符串,他们并不会修改调用它们的字符串。
- 字符串也可以被当成只读数组。使用方括号访问。
let s = 'Hello, world' console.log(s[0]) //'h' console.log(s[s.length-1]) //'d'
1.3.4 模板字面量
- ES6 及之后的版本,字面串字面量可以用反引号来定界
let name = 'Bill' let greeting = `Hello ${name}.` console.log(greeting) //'Hello Bill.'
位于 ${} 之间的内容都被当作 JavaScript 表达式来解释。而位于这对花括号之外的则是常规字符串字面量。
标签化模板字面量:String.raw()。这个函数返回反引号中未经处理的文本,即不会处理任何反斜杠转义。
注意:即使标签化模板字面量的标签部分是函数,在调用这个函数时也没有圆括号。在这种情况下,反引号字符充当开头和末尾的圆括号。
console.log(`\n`.length) //1: 字符串中只包含一个换行符 console.log(String.raw`\n`.length) //2: 一个反斜杠字符和一个字母n
1.3.5 模式匹配(简单介绍)
- JavaScript 定义了一种被称为正则表达式(RegExp)的数据类型,用于描述和匹配文本中的字符串模式。
/^HTML/ //匹配字符串开头的字母HTML /[1-9][0-9]*/ //匹配非0数字,后面跟着任意数字 /\bjavascript\b/i //匹配 'javasript' 这个词,不区分大小写
- RegExp 对象定义了一些有用的方法,而字符串也有接收 RegExp 参数的方法。
let text = 'testing: 1, 2, 3' let pattern = /\d+/g //匹配一个或多个数字 console.log(pattern.test(text)) //true: 存在匹配项 console.log(text.search(pattern)) //9: 第一个匹配项的位置 console.log(text.match(pattern)) //['1', '2', '3']: 所有匹配项的数组 console.log(text.replace(pattern,'#')) //'testing: #, #, #' console.log(text.split(/\D+/)) // ['', '1', '2', '3']: 基于非数字拆分
1.4 布尔值
- 布尔值表示真或假、开或关、是或否。这个类型只有两个值:true 和 false。
- JavaScript 的任何值都可以转换为布尔值。下面这些值都会转换为(因而可以被用作)布尔值 false:
在这里插入代码片