语法

  1. 严格模式 use strict
    在脚本开头加上这一行:“use strict”;
    ECMAScript 3 的一些不规范写法在这种模式下会被处理,对于不安全的活动将抛出错误。
    也可以单独指定一个函数在严格模式下执行,只要把这个预处理指令放到函数体开头即可:
function doSomething() { 
 "use strict"; 
 // 函数体 
}
  1. 语句
  • 加分号也有助于在某些情况下提升性能,因为解析器会尝试在合适的位置补上分号以纠正语法错误。
let sum = a + b // 没有分号也有效,但不推荐
let diff = a - b; // 加分号有效,推荐
  • 尽量使用代码块
// 有效,但容易导致错误,应该避免
	if (test) 
	console.log(test); 
	// 推荐
	if (test) { 
	console.log(test); 
}

变量

  1. var声明作用域
  • 函数作用域
  • 变量将在函数退出时被销毁
function test() { 
		var message = "hi"; // 局部变量
	} 
	test(); 
	console.log(message); // 出错!
  • 在函数内部省略var操作符,可以创建一个全局变量
function test(){
		message = "hi";
	}
	test();
	console.log(message);

不推荐这么做,可能会造成全局变量污染

  • 如果需要定义多个变量,中间用逗号隔开
var message = "hi", 
	found = false, 
	age = 29;

插入换行和空格缩进并不是必需的

  1. var声明变量提升
    使用下面的代码不会报错
function foo() { 
		 console.log(age); 
	 	var age = 26; 
		} 
		foo(); // undefined
相当于下面👇的代码
function foo() { 
		var age; 
 		console.log(age); 
 		age = 26; 
		} 
		foo(); // undefined
这就是所谓的“提升”,也就是把所有变量声明都拉到函数作用域的顶部
  1. let声明
  • let 声明的范围是块作用域
    var声明下👇
if (true) { 
 var name = 'Matt'; 
 console.log(name); // Matt 
} 
console.log(name); // Matt
  • let声明下👇 报错:没有定义
if (true) { 
 let age = 26; 
 console.log(age); // 26 
} 
console.log(age); // ReferenceError: age 没有定义
  • 嵌套使用相同的标识符不会报错,而这是因为同一个块中没有声明重复
var name = 'Nicholas'; 
console.log(name); // 'Nicholas' 
if (true) { 
 var name = 'Matt'; 
 console.log(name); // 'Matt' 
} 
let age = 30; 
console.log(age); // 30 
if (true) { 
 let age = 26; 
 console.log(age); // 26 
}
  • 对声明冗余报错不会因混用let和var而受影响,这两个关键字声明的并不是不同类型的变量,它们只是指出变量在相关作用域如何存在
var name; 
let name; // SyntaxError 
let age; 
var age; // SyntaxError
  1. 暂时性死区
    原因还是let声明的变量不会在作用域中被提升
// name 会被提升
console.log(name); // undefined 
var name = 'Matt'; 
// age 不会被提升
console.log(age); // ReferenceError:age 没有定义
let age = 26;
  1. 全局声明
    使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)
var name = 'Matt'; 
console.log(window.name); // 'Matt' 
let age = 26; 
console.log(window.age); // undefined
  1. 条件声明
    由于let的块级特性,不能依赖条件声明
<script> 
 let name = 'Nicholas'; 
 let age = 36; 
</script> 
<script> 
 // 假设脚本不确定页面中是否已经声明了同名变量
 // 那它可以假设还没有声明过
 if (typeof name === 'undefined') { 
 let name; 
 } 
 // name 被限制在 if {} 块的作用域内
 // 因此这个赋值形同全局赋值
 name = 'Matt'; 
 try { 
 console.log(age); // 如果 age 没有声明过,则会报错
 } 
 catch(error) { 
 let age;
  } 
 // age 被限制在 catch {}块的作用域内
 // 因此这个赋值形同全局赋值
 age = 26; 
</script>

4. for 循环中的 let 声明

  1. 使用 let 声明迭代变量时,JavaScript 引擎在后台会为每个迭代循环声明一个新的迭代变量。
for (let i = 0; i < 5; ++i) { 
 setTimeout(() => console.log(i), 0) 
} 
// 会输出 0、1、2、3、4

const 声明

const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误。

数据类型

6中简单的:Undefined、Null、Boolean、Number、String 和 Symbol。
1种复杂的:Object(对象)

typeof 操作符

对一个值使用 typeof 操作符会返回下列字符串之一:

  • "undefined"表示值未定义;
  • "boolean"表示值为布尔值;
  • "string"表示值为字符串;
  • "number"表示值为数值;
  • "object"表示值为对象(而不是函数)或 null;  "function"表示值为函数;
  • "symbol"表示值为符号。
let message = "some string"; 
console.log(typeof message); // "string" 
console.log(typeof(message)); // "string" 
console.log(typeof 95); // "number"

调用typeof null 返回的是"object"。这是因为特殊值 null 被认为是一个对空对象的引用

Undefined 类型

不初始化的变量和未定义的变量进行typedof操作得出的答案是一样的都是undefined
定义的变量的时候为了区分开来,尽量赋值初始值

let message; // 这个变量被声明了,只是值为 undefined 
 		// age 没有声明 
 		if (message) { 
 		 // 这个块不会执行
 		} 
 		if (!message) { 
 		 // 这个块会执行
 		} 
 		if (age) { 
 		 // 这里会报错
 		}

永远不必显式地将变量值设置为 undefined
undefined 是一个假值

Null类型

null 值表示一个空对象指针,给typeof 传一个 null 会返回"object"
保存对象值的变量时,建议使用 null 来初始化
undefined 值是由 null 值派生而来的

console.log(null == undefined); // true

null 是一个假值

Boolean 类型

有两个字面值:true 和 false。
Boolean()转型函数:

let message = "Hello world!"; 
let messageAsBoolean = Boolean(message);

javascript 红宝书电子版 js红宝书第三版pdf_赋值

let message = "Hello world!"; 
if (message) { 
 console.log("Value is true"); 
}

Number 类型

Number 类型使用 IEEE 754 格式表示整数和浮点值
十进制

let intNum = 55; // 整数

八进制
必须以0开头

let octalNum1 = 070; // 八进制的 56 
let octalNum2 = 079; // 无效的八进制值,当成 79 处理
let octalNum3 = 08; // 无效的八进制值,当成 8 处理

十六进制
必须以0x开头
前缀0x区分大小写,数字中的字母大小写均可

let hexNum1 = 0xA; // 十六进制 10 
let hexNum2 = 0x1f; // 十六进制 31
正零和负零在所有情况下都被认为是等同的
1.浮点值

定义浮点值,必须有小数点

let floatNum1 = 1.1; 
let floatNum2 = 0.1; 
let floatNum3 = .1; // 有效,但不推荐

因为存储浮点值内存空间是存储整数值的两倍,所以ES想方设法把值转换为整数。

let floatNum1 = 1.; // 小数点后面没有数字,当成整数 1 处理
let floatNum2 = 10.0; // 小数点后面是零,当成整数 10 处理

浮点值的精确度最高可达 17 位小数,但计算时不够精确

if (a + b == 0.3) { // 别这么干! 
 console.log("You got 0.3."); 
}
2.值的范围
  • Number.MAX_VALUE表示最大数值
  • Number.MIN_VALUE表示最小数值
    如果超出了js的范围,则会得到一个Infinity(无穷)值,或者以-Infinity(负无穷大)
    isFinite()函数可以确定一个值是不是有限大
let result = Number.MAX_VALUE + Number.MAX_VALUE; 
console.log(isFinite(result)); // false
3.NaN

NaN是一个特殊的值,意思是“不是数值”(Not a Number)
用于表示本来要返回数值的操作失败了(而不是抛出错误)

  • 任何涉及 NaN 的操作始终返回 NaN
  • NaN 不等于包括 NaN 在内的任何值,也就是不能与任何值比较
console.log(NaN == NaN); // false

提供了一个isNaN()函数,判断某个数据是否“不是数值”

console.log(isNaN(NaN)); // true 
console.log(isNaN(10)); // false,10 是数值
console.log(isNaN("10")); // false,可以转换为数值 10 
console.log(isNaN("blue")); // true,不可以转换为数值
console.log(isNaN(true)); // false,可以转换为数值 1
数值转换

三个函数可以将非数值转换为数值

  • Number()函数
  • 布尔值,true 转换为 1,false 转换为 0。
  • 数值,直接返回。
  • null,返回 0。
  • undefined,返回 NaN。
  • 字符串,只有是数字的时候才返回,非数字返回NaN
  • 空字符串返回0
let num1 = Number("Hello world!"); // NaN 
let num2 = Number(""); // 0 
let num3 = Number("000011"); // 11 
let num4 = Number(true); // 1
  • parseInt()函数
let num1 = parseInt("1234blue"); // 1234 
let num2 = parseInt(""); // NaN 
let num3 = parseInt("0xA"); // 10,解释为十六进制整数
let num4 = parseInt(22.5); // 22 
let num5 = parseInt("70"); // 70,解释为十进制值
let num6 = parseInt("0xf"); // 15,解释为十六进制整数

可以用第二个参数规定传入的进制类型

let num1 = parseInt("10", 2); // 2,按二进制解析
let num2 = parseInt("10", 8); // 8,按八进制解析
let num3 = parseInt("10", 10); // 10,按十进制解析
let num4 = parseInt("10", 16); // 16,按十六进制解析
  • parseFloat()函数
    和上面差不多
let num1 = parseFloat("1234blue"); // 1234,按整数解析
let num2 = parseFloat("0xA"); // 0 
let num3 = parseFloat("22.5"); // 22.5 
let num4 = parseFloat("22.34.5"); // 22.34 
let num5 = parseFloat("0908.5"); // 908.5 
let num6 = parseFloat("3.125e7"); // 31250000