1.变量作用域
1.如果一个变量在函数体内部声明,则该变量的作用域为整个函数体,函数体外不可引用。
var add = function(){
var a = 1;
}
a+1; // ReferenceError
2.如果两个函数各自声明了同一个变量,那么该变量只在各自的函数体内起作用。
var foo(){
var a = 1;
console.log(a); //1
}
var bar(){
var a= 'A';
console.log(a); // A
}
3.由于js函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来不可以
function outside(){
var outside = 1;
function inside(){
var inside = 2;
var add = outside + inside; //3
console.log(add);
}
console.log(add); // referenceError
}
4.如果外部函数和内部函数重名,内部函数变量会覆盖外部函数的变量
function out(){
var a = 1;
function in (){
var a = 2;
console.log(a); // 2
}
in();
console.log(a);
}
2.变量提升
js会把所有变量的声明提前到函数顶部
变量提升和函数提升是js设计缺陷,在其他语言中直接就报错了
不要使用变量提升与函数声明提升,所有变量和函数遵循先声明后使用的原则
不要在JS的设计缺陷中纠结,知道后避开坑 ---廖雪峰
3.全局作用域
不在任何一个函数内定义的变量就具有全局作用域。实际上,js有一个默认的全局对象window,全局作用域的对象实际上是绑定到window的一个属性。
var course = "learn js";
alert(course);
alert(window.course);
js实际上只有一个全局作用域,任何变量(函数也是),如果没有在当前的函数作用域中找到,就会继续向上查找,最后如果全局作用域也没有找到,则报ReferenceError.
4.局部作用域
js变量的作用域实际上是函数的内部,在for循环语句中是无法定义具有局部作用域的变量:
function foo(){
for(var i = 0;i<100;i++){
//
}
i+=100; //仍然可以引用变量i
}
为了解决块级作用域,ES6引入了新的关键字let,可以声明一个块级作用域。
function foo(){
var sum =0;
for(let i=0; i<100; i++) {
sum += i;
}
i +=1; // ReferenceError
}
5常量
在ES6之前,通常用全部大写的变量表示这是一个常量,不可修改值。
var PI = 3.14;
ES6中引入了新的关键字const来定义常量,const与let都具有块级作用域。
const PI = 3.14
常量一旦声明,不可修改
const(var) PI = 3.14;
PI = 3;
console.log(PI); //chrome报错 Identifier 'PI' has already been declared