变量的作用域:
1.不在任何函数内定义的变量具有全局性,实际上JavaScript默认有一个全局对象window,全局作用域的变量实际上绑定成了window的一个属性
2.不在函数中定义的函数(顶层函数),其实也就是window的一个属性。
var a = "我是一个全局变量";
console.log(a);//"我是一个全局变量"
console.log(window.a);//"我是一个全局变量"
var func1 = function(){
console.log('hello world');
}
func1();//'hello world'
window.func1();//'hello world'
变量提升:
1.JavaScript的函数有个特点,就是会先扫描整个函数的语句,将其中的变量自动提升到函数的顶部。
先给个代码大家看看会输出什么?
function func2(){
var a = 0;
console.log('a'=a);
console.log('b'=b);
var b = 1;
}
肯定有人觉得这个函数肯定会报错,因为b都还没声明就已经在使用了。其实输出结果是
a = 0
b = undefine
说明JavaScript引擎将变量的申明进行了提升,但是注意,这里仅仅是申明进行了提升,并没有把赋值也提升。所以这里b是undefined,而不是1.
名字空间:
1.我们知道全局变量会自动绑定到window对象上面。那么如果有多个js文件其中出现了相同的变量名,并且都是全局变量,那么就会导致命名冲突,并且不容易找出错误。所以名字空间就起作用了。
2.名字空间是将自己的所有变量和函数全部绑定到一个全局变量中。这样就能够保证不会出现命名冲突。
例如:
var MYAPP={}; //唯一的全局变量
MYAPP.name='myapp'; //将name这个变量变成MYAPP的属性
MYAPP.version=1.0;
MYAPP.foo=function(){ //将foo函数放到MYAPP中,成为它的属性
return 'foo';
};
var name='haha';
var foo1=function(){
return '全局foo1';
}
MYAPP.foo1=function(){
return '被绑定在MYAPP中的foo1';
};
console.log(MYAPP.foo()); //'foo'
console.log(MYAPP.name); //'myapp'
console.log(name); //'haha'
console.log(foo1()); //'被绑定在MYAPP中的foo1'
//许多著名的JavaScript库都是这样做的:jQuery,YUI,underscore等
块级作用域:
由于在JavaScript中变量作用域实际上是函数内部,所以例如在for循环中定义的变量,在外部依然可以引用。
例如:
function foo(){
for(var i=0;i<10;i++){
//
}
console.log(i); //此时还是会获取到i的值,9
}
所以在ES6中引入了let这个关键字,用let代替var可以创造一个块级作用域的变量
例如:
function foo(){
for(let i=0;i<10;i++){
//
}
console.log(i);// i is not defined
}
es6中还引入了一个定义常量的关键字 const:
在es6之前定义常量都是全部大写,来提示这是一个常量,但是这个常量还是可变的,并不像java中的final关键字。所以es6引入了一个新关键字,和java的final一样,就是const。专门用来定义常量。用const定义的变量不可以修改
例如:
const PI = 3.14;
PI = 6;//给PI重新赋值,有的浏览器会报错,有的不报错,但是修改之后没效果
console.log(PI); //3.14
注意:
const和let都是具有块级作用域的。个人觉得以后能用let的就不用var了。