前话
其实有些尴尬,因为之前我写了很多,结果忘记保存了~,这可真是个玩笑啊
js语句内容
语句,是 JavaScript 中组织代码的基础语法组件,包括函数声明等等在内的六种声明,其实都被归为“语句”的范畴。因此,如果将一份 JavaScript 代码中的所有语句抽离掉,那么大概就只会剩下为数不多的、在全局范围内执行的表达式了。所以
所有在语句内可以存在的东西只有四种:表达式、其它语句、标识符声明(取决于声明语句或其它的隐式声明的方式),以及一种特殊的语法元素,称为“标签(例如标签化语句,或 break 语句指向的目标位置)”。 ----查抄周爱民老师的文章
为什么要作用域
作用域,本质上只包括一组标识符。因此,只有当存在潜在标识符冲突的时候,才有必要新添加一个作用域来管理它们。例如函数,由于函数存在“重新进入”的问题,所以它必须有一个作用域来管理“重新进入之前”的那些标识符。这个东西想必你是听说过的,它被称为“闭包” ----查抄周爱民老师的文章
在如上的说法中,我们知道了这个作用域是来管理些标识符的。
所以标签、表达式和其它语句这三种东西都不需要使用一个“独立作用域”去管理起来。所谓“其它语句”当然存在这种冲突,不过显然这种情况下它们也应该自己管理这个作用域。所以,对于当前语句来说,就只需要考虑剩下的唯一一种情况,就是在“语句中包含了标识符声明”的情况下,需要创建块级作用域来管理这些声明出来的标识符。----查抄周爱民老师的文章
es5 and es6 变量声明
1.es5中只有两中声明变量的方式,var命令和function命令
2.es6除了添加let和const命令,还添加了两种声明变量的方法:import命令和class命令
在es5与es6中。其实会经常看到一些关于这两个作用域的区分问题。其实只要两句话,我们就能区分开了
!!!
var只有在全局域function中才有作用域被管理起来,
let/const = 存在块状作用域
但是为什么不把var也加入块级作用域呢,为了兼容,之前的es版本。所以在js的内部其实维护了两个变量的列表
所有”var 声明“和函数声明的标识符都登记为 varNames,使用“变量作用域”管理;
其它情况下的标识符 / 变量声明,都作为 lexicalNames 登记,使用“词法作用域”管理。
块级作用域
测试题
关于这个标题的提问,我想使用一个代码引出
var a = 1;
let b = -1;
if(true){
console.log('if里面:',a,b);
var a = 2;
let b = -2;
}
console.log('if后:',a,b);
for (let index = 0; index < 2; index++) {
var a = 3;
let b = -3;
};
console.log('for后:',a,b);
{
var a = 4;
let b = -4;
}
console.log('{}后:',a,b);
可以检测一下 自己能否回答上来这个问题。
我们需要使用到var的两个特性
var 1,可以重复定义变量
2,存在变量提升(其实ES6的文档规范中并不存在变量提升这个词 ,访问一个未初始化的绑定(uninitialized mutable/immutable binding)
为什么要使用var 来检测呢。使用如果一个作用域是新的作用域,必然会屏蔽外部的作用域,建立一个非全局作用域。其中创建变量这个var时候会存在变量的提升.在全局变量中存放一个一样的变量。然后读取这个变量是undefind的话。说明这个存在作用域,否则就会打印全局变量,说明并不存在作用域
顺序、分支、循环
语句,是 JavaScript 中组织代码的基础语法组件,包括函数声明等等在内的六种声明,其实都被归为“语句”的范畴。因此,如果将一份 JavaScript 代码中的所有语句抽离掉,那么大概就只会剩下为数不多的、在全局范围内执行的表达式了。所以,理解“语句”在 JavaScript 中的语义是重中之重。