二、语言基础
2.1语法
(简单的语法基础将在文章省略)
2.1.1严格模式
function doSomething() {
"use strict";
// 函数体
}
2.1.2语句
2.2变量
2.2.1var
var操作符定义的变量会成为包含它的函数的局部变量。如果在函数内省略var操作符,就会成为全局变量(不建议)
var具有声明提升,此外,可以反复多次用var声明同一个变量
2.2.2 let
let 声明的范围是块作用域,且不允许出现冗余声明。
var和let区别:
var是函数作用域,let是块作用域
if (true) { var name = 'Matt'; console.log(name); // Matt } console.log(name); // Matt if (true) { let age = 26; console.log(age); // 26 } console.log(age); // ReferenceError: age 没有定义
(JavaScript 引擎会记录用于变量声明的标识符及其所在的块作用域,嵌套使用相同的标识符不会报错)
let age=26
if(true){
let age=30;
console.log(age)//30
}
1.暂时性死区
在let中,如果引用未声明的变量,则会抛出出 ReferenceError,并且将其称为暂时性死区
2.全局声明
3.条件声明
因为 let 的作用域是块,所以不可能检查前面是否已经使用 let 声明过同名变量,同时也就不可能在没有声明的情况下声明它(参考暂时性死区)
<script>
let age = 26;
</script>
<script>
// 假设脚本不确定页面中是否已经声明了同名变量
// 那它可以假设还没有声明过,即age=26还未被声明过
let age = 36;
// age 之前声明过,这里会报错
</script>
4.for循环中的let声明
在let出现之前,一直用的var声明i,则将会导致,i渗透到循环体外部
for (var i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
// 实际上会输出 5、5、5、5、5
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
// 会输出 0、1、2、3、4
执行超时逻辑会被放在循环结束之后,此时var则是退出循环的值:5。而如果使用let,那么每次循环都会有一个新的let,赋值分别为0,1,2,3,4
2.2.3 const
显著区别:声明变量时必须同时初始化变量
1.const后续不能修改变量,不能重复声明
2.const的作用域是块
const name='123'
if(true){
const name='11'
}
console.log(name) //123
3.const 声明的限制
虽然for循环不能用const来声明迭代变量但是可以将const 用于for...in和for...of,相当于每次循环都创建了一个新的const
建议使用变量声明优先级:const>let>var
2.3数据类型
2.3.1typeof
console.log(typeof '123')//string
注意:调用typeof null 返回的是"object"。这是因为特殊值 null 被认为是一个对空对象的引用
严格来讲,函数在 ECMAScript 中被认为是对象。可是, 函数也有自己特殊的属性。为此,就有必要通过 typeof 操作符来区分函数和其他对象
2.3.2undefined类型
但是未声明的变量使用typeof也是undefined,因为他们都属于无法执行实际操作
2.3.3null类型
null 是一个假值,但也有其他可能是假值的情况
let message = null;
let age;
if (message) {
// 这个块不会执行
}
if (!message) {
// 这个块会执行
}
if (age) {
// 这个块不会执行
}
if (!age) {
// 这个块会执行
}
2.3.4boolean类型
注意:布尔值字面量 true 和 false 是区分大小写的,因此True和False并不为布尔值
Boolean | true | false |
Number | 非零值(包括无穷) | 0,NaN |
Object | 任意对象 | null |
Undefined | N/A(不存在) | undefined |
2.3.5Number类型
八进制:第一个数字必须是0,然后是相应的八进制数字(数值 0~7)。如果字面量中包含的数字超出了应有的范围,就会忽略前缀的零,后面的数字序列会被当成十进制数
(严格模式下八进制无效)
十六进制:前缀 0x(区分大小写),然后是十六进制数字(0~9 以及 A~F,字母大小写均可)
使用八进制和十六进制格式创建的数值在所有数学操作中都被视为十进制数值
注意:+0和-0在所有情况下都被认为是相等的
- 浮点值
let floatNum = 3.125e7; // 等于 31250000,乘10的7次幂
注意:因为浮点数精度不高,所以0.1+0.2!==0.3
2. 值的范围
console.log(0/0); // NaN
console.log(-0/+0); // NaN
console.log(isNaN(NaN)); // true
console.log(isNaN("10")); // false,可以转换为数值 10
console.log(isNaN("blue")); // true,不可以转换为数值
console.log(isNaN(true)); // false,可以转换为数值 1
4.数值转换
Number()函数
- null,返回0
- undefined,返回NaN
- 字符串
- 字符串数值直接转换为数值(包括浮点数字符串)
- 字符串包含有效十六进制,则将其转换为十进制
- 空字符串为0
- 其余返回NaN
- 对象,调用 valueOf()方法,并按照上述规则转换返回的值
parseInt()函数
-
从第一个非空格字符开始转换。如果第一个字符不是数值字符、加号或减号,parseInt()立即返回 NaN。这意味着空字符串也会返回 Na
-
如果第一个字符是数值字符、加号或减号,则继续依次检测每个字符,直到字符串末尾,或碰到非数值字符。比如"1234blue"会被转换为 1234,因为"blue"会被完全忽略
-
parseInt()函数也能识别不同的整数格式(十进制、八进制、十六进制),parseInt()也接收第二个参数,用于指定底数(进制数),如parseInt("0xAF", 16)
-
从位置 0 开始检测每个字符。同样,它也是解析到字符串末尾或者解析到一个无效的浮点数值字符为止。这意味着第一次出现的小数点是有效的,但第二次出现的小数点就无效
-
parseFloat()只解析十进制值
-
如果字符串表示整数(没有小数点或者小数点后面只有一个零),则 parseFloat()返回整数