curTain

一、语法

1.1 变量命名规则

  1. 第一个字符必须是一个字符、下划线(_)或美元符号($)
  2. 剩下的字符可以是字母、下划线、美元符号和数字,也可以是 Unicode 的字母字符

1.2 严格模式

概念:ES5 添加了严格模式,严格模式是一个预处理指令,严格模式的目的是处理一些不规范写法,对于不安全的活动抛错误

如何添加严格模式:

1
2
3
4
5
6
7
8
// 在脚本开头添加一行
"use strict"

// 或在函数体内第一行添加
function fn(){
"use strict"
// 函数体
}

严格模式的影响:

1.2.1 针对变量:

  1. 不允许以外创建全局变量,给一个没有声明的变量赋值,抛错 ReferenceError 引用错误
  2. 不能对变量使用 delete 操作符
  3. 不能使用保留字作为变量名

案例:

1
2
3
4
5
6
7
8
// 非严格模式:创建全局变量 
// 严格模式:抛出 ReferenceError
name = "tan";

//非严格模式:静默失败
//严格模式:抛出 ReferenceError
var color = "red";
delete color;

1.2.2 针对对象:

  1. 为只读属性赋值会抛出 TypeError
  2. 对不可配置的属性(noConfigurable)使用 delete 操作会抛出 TypeError
  3. 对不可扩展的对象添加属性会抛出 TypeError
  4. 使用对象字面量时,属性名必须唯一

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
let obj = {}

Object.defineProperty( obj, "name", {
configurable: true,
enumerable: true,
// read-only
writable: false,
value: "tan"
})

// 非严格模式: 默认修改失败
// 严格模式: 抛出错误 Cannot assign to read only property "name"
obj.name = "yu"

1.2.3 针对函数:

  1. 要求命名函数的参数必须唯一
  2. 在非严格模式下,修改命名参数的值会反映到 arguments 对象中,而在严格模式下,值是独立的
  3. arguments.callee 和 arguments.caller,在非严格模式下,这两个属性一个引用函数本身,一个引用调用函数。而在严格模式下,访问哪个属性都会抛出 TypeError
  4. 只能在脚本的顶级和函数内部生命函数

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//非严格模式: 没有错误,后面的参数覆盖前面的值
//严格模式: 抛出语法错误
function fn( num, str, num ){
// 非严格模式:undefined 12
// 严格模式: 抛出语法错误
console.log( num, str )
}
fn( 12, "tan" )

//非严格模式: 修改会反映到 arguments 中
//严格模式: 修改不会反映到 arguments 中
function showValue(value) {
value = "yu";
console.log(value); // "yu"
console.log(arguments[0]); // 非严格模式:"yu",严格模式:"tan"
}
showValue("tan");

//访问 arguments.callee
//非严格模式:没有问题
//严格模式:抛出 TypeError
function factorial(num){
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num-1)
}
}
var result=factorial(5);

//在 if 语句中声明函数
//非严格模式:将函数提升到 if 语句外部
//严格模式:抛出语法错误
if (true){
function doSomething(){
// todo
}
}

1.2.4 针对 eval() 函数中的变量

  1. 在严格模式中,它在包含上下文中不再创建变量或函数
  2. 在 eval() 函数中声明的变量和函数,只在特殊的终于用中有效,随后将被销毁

案例:

1
2
3
4
5
6
7
8
9
//使用 eval()创建变量
//非严格模式:弹出对话框显示 10
//严格模式:调用 alert(x)时会抛出 ReferenceError
eval("var x=10");
console.log(x);

"use strict";
var result = eval("var x=10, y=11; x+y");
alert(result); // 21 执行结果存在变量内

1.2.5 抑制 this 指向

在非严格模式下使用函数的 apply()或 call()方法时,null 或 undefined 值会被转换为全局 对象。而在严格模式下,函数的 this 值始终是指定的值,无论指定的是什么值

案例:

1
2
3
4
5
6
7
8
// 访问属性
// 非严格模式: 传入null, 函数的this值是全局对象
// 严格模式: 抛出错误,因为this的值为 null
var color = "red";
function displayColor(){
console.log(this.color);
}
displayColor.call(null);

1.2.6 其他影响

  1. 严格模式去掉了 JavaScript 中的八进制字面量
  2. 严格模式下 parseInt()的行为,八进制字面量在严格模式下会被当作以 0 开头的十进制字面量

案例:

1
2
3
4
5
6
7
8
9
//使用八进制字面量 
//非严格模式:值为 8
//严格模式:抛出语法错误
var value = 010;

//使用 parseInt()解析八进制字面量
//非严格模式:值为 8
//严格模式:值为 10
var value = parseInt("010");

1.2.7 总结

简单的概括一下,严格模式会造成以下影响:

  1. 变量必须定义后才能赋值,且不能随意删除
  2. 修改对象中只读属性和不可配置的属性时,会报错
  3. 函数中,arguments 与参数独立,操作互不影响
  4. 显式绑定 this 时,不能将函数绑定到 null 上
  5. 其他影响,eval 函数执行中的变量定义和定义数字时的进制问题

严格模式的目的:

  1. 消除 js 语法不严谨的地方,减少奇怪行为(不定义变量,直接赋值,八进制数字)
  2. 消除代码运行不安全的地方(修改只读属性)
  3. 提高编译效率和运行速度
  4. 为未来做铺垫

二、变量

有三个关键字可以声明变量:varletconst

2.1 var、let、const 的区别

关键字 变量提升 块级作用域 重新赋值 重复声明
var 存在 不存在 可以 可以
let 不存在 存在 可以 不可以
const 不存在 存在 不可以 不可以

注意:

  1. const 必须初始化一个值
  2. var 声明的变量在浏览器环境会挂载到 window 上,而 let 和 const 不会

2.2 var、let、const 的使用

  1. 不使用 var 定义变量
  2. 使用 let 定义需要改变的基础变量
  3. 使用 const 定义常量或不会直接更改引用的对象

三、数据类型

ECMAScript 有其中简单数据类型(原始类型):

  1. number
  2. string
  3. boolean
  4. null
  5. undefined
  6. symbol
  7. bigInt

复杂数据类型:object(包含对象、function)

3.1 typeof 操作符

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

  1. undefined 表示值未定义
  2. boolean 表示值为布尔值
  3. string 表示值为字符串
  4. number 表示值为数字
  5. object 表示值为对象(不是函数)或 null
  6. function 表示值为函数
  7. symbol 表示值为符号
  8. bigint 表示值为bigint

案例:

1
2
3
4
5
6
7
8
9
10
typeof undefined  // undefined
typeof null // object
typeof true // boolean
typeof "tan" // string
typeof 12 // number
typeof 12n // bigint
typeof { name: "yuuu" } // object

function fn(){}
typeof fn // function

 评论