三、语言基础

61 阅读6分钟

JavaScript 高级程序设计(第四版)

三、语言基础

(一)语法

1.区分大小写

变量test和Test不同

2.标识符

(1)第一个字符必须为字母、下划线(_)或$,剩下的可以是字母、下划线、美元符号或数字,按照惯例,标识符使用驼峰写法(menuList)。

(2)标识符不能为关键字: a ECMA-262第6版规定的所有关键字 b ECMA-262第6版为将来保留的所有词汇

始终保留

严格模式下保留

模块代码中保留

3.严格模式

一种不同于JavaScript解析和执行模型,处理es3中不规范写法,对不安全活动抛出错误

'use strict'

(1)脚本开头

(2)函数内部

function () {
  'use strict'
}

4.语句

(1)最好在语句最后使用分号

(2)类似

if (test) {
   console.log(test)
};

不要省略为

if (test) console.log(test);

5.变量

var 定义变量关键字

var 声明的变量可以再次改变变量值类型,但是不推荐

text1 var声明的变量具有函数作用域,该变量在函数退出时销毁

text2 函数作用域内变量未声明直接赋值会成为全局变量。不推荐,严格模式下会报错

text3 声明提升:var声明的变量会将变量声明提升到函数作用域顶部

text4 可反复声明,值为最后一个

console.log(text3); //undefined
function test() {
    var text1 = 'wen'
    text2 = 123
}
test()
var text3 = '123'
console.log(text1); //Uncaught ReferenceError: text is not defined
console.log(text2); //123
var text4 = 1
var text4 = 2
var text4 = 3

let const

let const声明的为块级作用域 代码块{} 嵌套使用相同标识符不会出错

let num1 = 1
console.log(num1); // 1
if (!num1) {
    let num1 = 2 
    console.log(num1); // 2  
}

不可重复声明 var 和 let或const 声明同一个变量也会报错

没有变量提升,在let声明之前的执行瞬间称为‘暂时性死区’

const 声明的变量称为常量,必须拥有初始值。 且不能改变引用,即声明位于栈的简单数据类型不能改变值,声明位于堆的对象不能改变引用地址,但可以改变内部属性值

不能用const声明会自增的迭代变量,因为改变了值,违反const规则

for 循环中的var 和 let

var

1.var 声明的i 作用域为全局,所以for循环外也可以打印

for (var i = 0; i < 5; ++i) {}
console.log(i); // 5

let 声明的i 作用域为块级,所以for循环外获取不到i,报错

for (let i = 0; i < 5; ++i) {}
console.log(i); // Uncaught ReferenceError: i is not defined

var 每次for循环迭代变量为同一变量因此打印的为最终退出循环的变量 5

for (var i = 0; i < 5; ++i) {
    setTimeout(() => {
        console.log(i) // 5 5 5 5 5
    }, 0);
}

事件执行顺序

首先执行第一次for 循环 var i = 0 然后遇到异步任务 setTimeout 放到任务队列
第二次 var i = 1 遇到setTimeout 放到任务队列
第三次 var i = 2 遇到setTimeout 放到任务队列
第四次 var i = 3 遇到setTimeout 放到任务队列
第五次 var i = 4 遇到setTimeout 放到任务队列
第六次 i = 5 不满足条件,跳出循环,此时 var i = 5
此时再从任务队列中取出setTimeout 打印,均会打印出5,
所以最终结果为:5 5 5 5 5

let 每次for循环迭代变量为不同代码块变量

for (let i = 0; i < 5; ++i) {
    setTimeout(() => {
        console.log(i) // 0 1 2 3 4
    }, 0);
}

事件执行顺序
首先执行第一次for 循环 let i = 0 然后遇到异步任务 setTimeout 放到任务队列
第二次 let i = 1 遇到setTimeout 放到任务队列
第三次 let i = 2 遇到setTimeout 放到任务队列
第四次 let i = 3 遇到setTimeout 放到任务队列
第五次 let i = 4 遇到setTimeout 放到任务队列
第六次 i = 5 不满足条件,跳出循环,let i = 5
此时再从任务队列中取出setTimeout 打印,由于每次打印时let声明的i为块级作用域,所以setTimeout打印的为该作用域内的i
所以最终打印结果为:0 1 2 3 4

声明风格最佳实践
const > let > var(尽量不使用)

6.数据类型

(1) typeof 用来检测任意变量的数据类型

let text1;
let s = Symbol('foo')
function test() {}
console.log(typeof 1); //number
console.log(typeof '1'); //string        
console.log(typeof true); //boolean         
console.log(typeof undefined); //undefined              
console.log(typeof text2); //undefined          
console.log(typeof text); //undefined          
console.log(typeof null); //object
console.log(typeof test); //function    
console.log(typeof s); //symbol

(2) Undefined 假值,理论上来说无法进行实际操作

声明变量但未赋值,值初始化为undefined,一个未声明的变量通过typeof检测都是undefined,但其实不一样

(3)Null 空对象指针,在初始化将来要保存对象的变量时,赋值为null

console(undefined == null)   //true ==操作符会转换操作数

(4)Boolean

true
非空字符串、非零数值(包括无穷值)、任意对象、N/A
false:
''、0,NaN、null、undefined

(5)Number

浮点值
包含小数点且小数点后至少有一个数字
存储浮点值是整值的两倍,所以ECMAScript总会把1.当初1处理,10.0当成10处理

科学计数法
数值后跟一个大写或小写e,e后面跟10的几次方 1.1e3 等于 1100
3.125e7 等于 31250000
3e-7 等于 0.0000003

值的范围
最小值:Number.MAX_VALUE
最大值:Number.MIN_VALUE

如果超出该范围 表示为Infinity或-Infinity

isFinite()用来确定值是不是有限大

const res = Number.MAX_VALUE + Number.MAX_VALUE
console.log(isFinite(res)); //false
console.log(Number.NEGATIVE_INFINITY); // -Infinity
console.log(Number.POSITIVE_INFINITY); // Infinity

NaN

不是数值,用于本来要返回数值的操作结果失败了,不是抛出错误

console.log(0 / 0); //NaN 
console.log(-0 / +0); //NaN
console.log(5 / 0); //Infinity
console.log(5 / -0); //-Infinity

// 任何涉及NaN的操作数都返回NaN
// NaN不等于任何值,包括自身

console.log(NaN == NaN); //false

// isNaN判断传入的参数是否是非数值,可以判断对象

console.log(isNaN(NaN)); //true
console.log(isNaN(false)); //false  布尔值可以转换为1、0

数值转换

Number()

转型数据,可以用于任何数据类型 布尔值:true 1;false 0 数值:直接返回 null:0 undefined:NaN 字符串: 如果字符串是有效的数值或者十六进制数,10进制直接转换为对应的数值,忽略前面的0,十六进制转换为10进制 空字符串:0 其他情况:NaN

parseInt()

用来转换整数值 字符串第一值如果不是数值、加减号,立即返回NaN,因此空字符串为NaN

console.log(parseInt('P1'));       //NaN
console.log(parseInt('1P'));       //1
console.log(parseInt('11.2POI'));  //11
console.log(parseInt(''));         //NaN

接受第二个参数用来解析不同进制数

console.log(parseInt('0xAF', 16));  //175
console.log(parseInt('AF', 16));    //175 可以省略0x,在传入第二个参数后
console.log(parseInt('AF'));        //NaN

console.log(parseInt('12', 2));     //1
console.log(parseInt('12', 8));     //10
console.log(parseInt('12', 10));    //12
console.log(parseInt('12', 16));    //18

parseFloat()

和parseInt规则一致,但有两个地方不同 可以转换第一个小数点;没有第二个参数,始终解析十进制数

console.log(parseFloat('0xAF'));     //0
console.log(parseFloat('010.1.1'));  //10.1
console.log(parseFloat('1.2e5'));    //12000