第三章 语言基础 JS红宝书笔记

语法

  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;
    

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

  2. 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;
      
    2. 全局声明
      使用 let 在全局作用域中声明的变量不会成为 window 对象的属性(var 声明的变量则会)
      var name = 'Matt'; 
      console.log(window.name); // 'Matt' 
      let age = 26; 
      console.log(window.age); // undefined
      
    3. 条件声明
      由于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 声明

    使用 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);

转换规则

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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值