一、块级作用域
在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。
js没有块级作用域(你可以自己闭包或其他方法实现),只有函数级作用域,函数外面的变量函数里面可以找到,函数里面的变量外面找不到。
var a=10;
function aaa(){
alert(a);
};
function bbb(){
var a=20;
aaa();
}
bbb(); //结果为10,因为aaa()函数不能访问到bbb()里面的局部变量,所以访问到的是a=10,这个全局变量。
二、全局变量
变量在函数外定义,即为全局变量。
全局变量有 全局作用域: 网页中所有脚本和函数均可使用。
当函数被定义时,函数对象内部不仅包含了代码逻辑,还定义了一个内部属性[[Scope]]引用了一条作用域链(可以理解成为一个对象列表)。如果这个函数在全局环境下被定义,那这个作用域链里就只有全局作用域。
var a=10;
function aaa(){
alert(a);
};
aaa(); //a 为外部变量即全局变量,所以可以直接访问到 结果为10
不用var 定义变量时,会默认为是全局变量(不规范,不推荐)
function aaa(){
a=10;
}
aaa();
alert(a); //结果为10;
//等价于:
var a;
function aaa(){
a=10;
};
aaa();
alert(a);
给未声明的变量赋值时,此变量就会变成全局变量。例如:var a=b=10; 可以解析成 b=10;var a=b; 也就是b为全局变量,a为局部变量,所以外部访问a访问不到,访问b结果为10;所以为了避免出现这种隐患,我们在定义变量的时候把所有要定义的变量都加上var。
function aaa(){
var a=b=10;
}
aaa();
alert(a);//结果为,无法访问到
alert(b);//结果为10;
变量的查找是就近原则,去寻找var定义的变量,当就近没有找到的时候就去查找外层;第二点,变量的声明被提前到作用域顶部,赋值保留在原地,如下示例:
function aaa(){
alert(a);
var a=20;
}
aaa(); //结果为:undefined
/**************/
var a=10;
function aaa(){
alert(a);
var a=20;
}
aaa(); //结果为:undefined
可以解析为是:
var a=10;
function aaa(){
var a; //声明提前了
alert(a);
a=20; //赋值扔留着原地
}
aaa();
三、局部变量
变量在函数内声明,变量为局部作用域。
局部变量:只能在函数内部访问。
因为局部变量只作用于函数内,所以不同的函数可以使用相同名称的变量。
局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁。
function aaa(){
var a=10;
};
aaa();
alert(a); //a 为函数aaa()内部变量量即局部变量,所以无法访问到
当参数跟局部变量重名的时候,优先级是等同的。
var a=10;
function aaa(a){
alert(a);
var a=20; //因为 a 是形参,优先级高于 var a; 所以 局部变量a的声明其实被忽略了。
}
aaa(a); //结果为:10
变量修改的时候另一个变量会跟着变化,但是当变量重新被定义时,则另一个不变化。
var a=[1,2,3];
var b=a;
b.push(4);
alert(a);//结果为[1,2,3,4] 当b改变的时候a也发生了改变
当b重新被赋值的时候 a不会改变.示例:
var a=[1,2,3];
var b=a;
b=[1,2,3,4]
alert(a)//结果为[1,2,3]