JavaScript——变量作用域
在js中,var定义的变量实际是有作用域的,假设在函数体中声明,则在函数体外不可使用(如果要使用,可以用闭包)
测试:
function text(){
var i = 1;
i = i+1;
}
i = i+2;//报错:Uncaught ReferenceError: i is not defined
- 两个函数可以使用相同的变量名,只要在函数内部,就不会冲突
function text(){
var i = 1
i = i+1
}
function text1(){
var i = 2
i = i+3
}
- 内部函数可以访问外部函数的变量,但反之不可以
function text(){
var i = 1;
console.log(i);
function text1(){
var m = i+2;
console.log(m);
}
var n = m+1;
text1()
}
text()
- 假设内部函数变量和外部函数变量重名
测试:
function pc(){
var i = 1;
function pc1(){
var i = 'A';
console.log('inner' +i);//outer1
}
console.log('outer'+i);//innerA
pc1()
}
pc()
在js中,函数查找变量从自身函数开始,是由“内”向“外”查找,假设外部存在同名的函数变量,则内部函数会屏蔽外部函数的变量
- 提升变量的作用域
function pc(){
var x = 'x'+y;//提升了y的作用域
console.log(x)
var y = 'y';
}
pc()
结果:xundefined
说明:js执行引擎自动提升了y的作用域声明,但没有提升y的赋值,所以结果中y的值才是undefined
规范:把所有的变量都定义在函数的头部,便于代码的维护
function pc(){
var x =1,
y =2,
z,m,n//未赋值的都是undefined,最后一个不用逗号
//定义之后随便用
}
全局作用域var
全局变量
//全局变量
var x = 1;
function pc(){
console.log(x)
}
console.log(x)
pc()
全局对象window:默认的所有的全局变量都会绑定在window对象上
var x = 1;
alert(x);
window.alert(x);//结果出现两次弹窗,说明alert()这个函数也是window变量
测试:
var x = 1;
window.alert(x);
var old_alert = window.alert;
//old_alert(x);
window.alter = function(){
};
window.alter(2);//发现此时alter()失效了,被old_alert()掩盖了
window.alert = old_alert; //恢复
window.alert(x);
javascript实际上只有一个全局作用域,任何变量(函数也可视作变量),假设没有在函数范围内找到,就会向外查找,如果在全局作用域都没有找到,就会报错( ReferenceError)
拓展问题:
由于所有的全局变量都绑定在window对象上,当不同的js文件引用了相同的全局变量时,会产生冲突,冲突该如何解决?
解决方法:定义一个唯一全局变量,然后把所有的变量都绑定到唯一全局变量上,而不是绑定到window上
//定义唯一全局变量pengApp
var pengApp = {};
//定义全局变量
//属性 以后调用name属性用pengApp.name
pengApp.name = "神明";
//方法
pengApp.add=function(a,b){
return a+b;
}
局部作用域let
全局作用域和局部作用域的区别
全局
function text(){
for(var i=1 ;i<100;i++ ){
console.log(i);
};
console.log(i+1);//发现i出了函数作用域还可以用
}
text()
局部
function text(){
for(let i=1 ;i<100;i++ ){
console.log(i);
};
console.log(i+1);
}
text()
Es6关键字let,解决了局部作用域冲突问题,建议使用let定义局部作用域的变量
定义常量const
ES6之前定义常量的方式:全部用大写字母定义的变量就是常量,建议不要修改
漏洞:不遵守规范常量可以被修改
var PI = 3.14;
console.log(PI);
var PI = 123;
console.log(PI);
3.14
123
因此在ES6引入新特性const,一旦定义后不能修改,修改则会报错
const PI = 3.14;
console.log(PI);
3.14