- 作用域就是决定变量有效范围
- 作用域按决定的时期来区分可分为词法作用域和动态作用域
词法作用域: 词法作用域就是作用域是由你在写代码声明时决定的,js是词法作用域
动态作用域: 动态作用域则是由调用时决定的. - 在es6之前,js中的作用域大多数由全局作用域和函数作用域组成,es6之后就有了块级作用域
函数作用域:在函数中会产生一个作用域,可以使内容私有化,规避冲突,避免全局污染
function test() {
var a = 0;
console.log(a); //0
}
console.log(a);//a is not defined
块级作用域:在{}之间会产生作用域
{
const a = 2;
console.log(a); //2
}
console.log(a); // a is not defined
- 在之前es5的时候,只有函数作用域,会带来一些比较恶心问题.
for (var i = 0; i < 20; i++) {
console.log(i);
}
console.log(i); //20 for循环后i还能访问,并且保留在20
if(false){
var a = 2; //因为没有块级作用域的存在,var a会被提升到if之前,也就是if里面的代码无论执行不执行都会提升
}
console.log(a); //undefined 不是 a is not defined
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i); //10个10
})
}
//因为没有块级作用域,i的值在{}之间并不会被保留下来,一旦有异步操作,就会拿到异步最后的那个值
- 变量声明的提升,var 声明变量和function声明函数,声明都会提升到当前作用域的顶端,function优先级比var优先级大,也就是function和var变量名称相同时,function的会把var的覆盖了,只有function的生效了
test(); //1
function test() {
console.log(1);
}
实际提升
function test() {
console.log(1);
}
test(); //1
- es6引进了const和let,两者声明的变量作用域规则就是按照块级作用域来,上面遇到的几个问题,全部用let或const声明,就不会有之前的问题
- const let 和 var 区别
const let 没有声明的提升,会产生块级作用域,即使申明全局变量,也不会变为window的一个属性,const和let重复声明会报错
const和let之间的区别,const基础类型数据不能修改,let可以修改.那const引用类型的变量为何就能修改了?原来变量存储的都是在栈里面的东西,里面能放一些比较小,有固定长度的数据,例如基本类型的数据,但是如果是一个引用类型的,里面放的就是一个指针,指向堆里面内存某一块,那个才是真正存储引用类型数据的地方,所以const监控的只是栈上面存放的东西,只要指针指向的地址不修改,实际数据可以怎么改动都可以.
网友评论