JS 变量提升
- JS 中,函数及变量的声明都将被提升到函数的最顶部
- JS 中,变量可以在使用后面声明,也就是变量可以先使用再声明
以下两个实例都将获得同样的结果
// 实例1:先使用变量再声明
x =5;
elem = document.getElementById("demo");
elem.innerHTML = x;
var x;
// 实例2:先声明变量再使用
var x;
x = 5;
elem = document.getElementById("demo");
elem.innerHTML = x;
JS 变量初始化不会提升
- JS 只有声明的变量会提升,初始化的不会被提升
以下两个实例的结果不同
// 实例1
var x = 5;
var y = 7;
elem = document.getElementById("demo");
elem.innerHTML = x + " " + y; // 结果显示为:5 7
// 实例2
var x = 5; // 初始化 x
elem = document.getElementById("demo");
elem.innerHTML = x + " " + y; // 结果显示为:5 undefined
var y = 7; // 初始化 y
实例解析
- 实例2的 y 输出了 undefined ,这是因为变量声明(var y )提升了,但是初始化(y = 7 )并不会提升,所以 y 变量是一个未定义的变量
实例2类似以下代码
var x = 5; // 初始化 x
var y; // 声明 y
elem = document.getElementById("demo");
elem.innerHTML = x + " " + y; // 结果显示为:5 undefined
y = 7; // 初始化 y
在头部声明所有变量
- 对于大多数程序员来说并不知道 JS 变量提升
- 如果程序员不能很好地理解变量提升,他们写的程序就容易出现一些问题
- 为了避免这些问题,通常我们在每个作用域开始前声明这些变量,这也是正常的 JS 解析步骤,易于理解
JS 严格模式
- JS 严格模式,即在严格的条件下运行
使用 "use strict" 指令
- "use strict" 指令在 JavaScript 1.8.5(ECMAScript5)中新增
- "use strict" 指令只允许出现在脚本或函数的开头
- 它不是一个语句,但是是一个字面量表达式,在 JS 旧版本中会被忽略
- "use strict" 的目的是指定代码在严格条件下执行
- 严格模式下不能使用未声明的变量
严格模式声明
- 严格模式通过在脚本或函数的头部添加"use strict"表达式来声明
"use strict";
x = 3.14; // 报错(x 未定义)
"use strict";
myFunction();
function myFunction() {
y = 3.14; // 报错(y 未定义)
}
- 在函数内部声明是局部作用域(只在函数内部使用严格模式)
x = 3.14; // 不报错
myFunction();
function myFunction() {
"use strict";
y = 3.14; // 报错(y 未定义)
}
为什么使用严格模式
- 消除 JS 语法的一些不合理、不严谨之处,减少一些怪异行为
- 消除代码运行的一些不安全之处,保证代码运行的安全
- 提高编译器效率,提高运行速度
- 为未来新版本的 JS 做好铺垫
- 严格模式体现了 JS 更合理、更安全、更严谨的发展方向
- 同样的代码,在严格模式中,可能会有不一样的运行结果
- 一些在正常模式下可以运行的代码,在严格模式中将不能运行
严格模式的限制
- 不允许使用未声明的变量(对象也是一个变量)
- 不允许删除变量或对象
- 不允许变量重名
- 不允许使用八进制
- 不允许使用转义字符
- 不允许对只读属性赋值
- 不允许对一个使用 getter 方法读取的属性进行赋值
- 不允许删除一个不允许删除的属性
- 变量名不能使用 "eval" 字符串
- 变量名不能使用 "arguments" 字符串
- 不允许使用这种语句:with (Math) {x = cos(2)} // 报错
- 出于一些安全原因,在作用域 eval() 创建的变量不能被调用
- 禁止 this 关键字指向全局对象
严格模式新增的保留关键字
- implements
- interface
- let
- package
- private
- protected
- public
- static
- yield