一、 js没有块级作用域(可以自己闭包或其他方法实现),只有函数级作用域,函数外面的变量函数里面可以找到,函数里面的变量外面找不到。
var a=10;
function fn(){
console.log(a); //
}
function fn1(){
var a=20;
fn();
}
fn1();
程序执行过程:
step-1:调用 fn1()
step-2:执行fn1(),声明局部变量a=2 ;调用 fn()
step-3:执行fn(),fn()中的a是全局变量,所以打印10
二、没有var直接赋值的变量都属于全局变量,即使在函数内部。
function fn(){
var a=b=10;
}
fn();
console.log(b);//
console.log(a);//Uncaught ReferenceError: a is not defined
var a=b=10 相当于 b=10;var a=b; 这种写法在函数内,b是全局变量,a是局部变量。执行完fn(),在console.log(b),会弹出10,在console.log(a)会报错。
三、 变量的查找是就近原则,去寻找var定义的变量,当就近没有找到的时候就去查找外层。
var a=10;
function fn(){
var a=20;
console.log(a);//
}
fn();
四、变量预解析
var a=10;
function fn(){
console.log(a);//undefined
var a=20;
}
fn();
所谓的预解析就是:在当前作用域中,JavaScript代码执行之前,浏览器首先会默认的把所有带var和function声明的变量进行提前的声明或者定义。
函数fn()的执行过程为:
step-1:var a
step-2:console.log(a)
step-3:a=10
当执行到console.log(a)时,还没有给局部变量a赋值,所以是undefined。
五、当参数跟局部变量重名时,优先级是等同的。
var a=10;
function fn(a){
console.log(a);//
var a=20;
}
fn(a);
六、指向同一地址的两个引用类型的变量,变量修改的时候另一个变量会跟着变化,但是当变量重新被赋值时,则另一个不变化。
var a=[0,1,2];
var b=a;
b[3]=3;//变量b被修改,a也跟着修改
console.log(a);//[0,1,2,3]
var a=[0,1,2];
var b=a;
b=[0,1,2,3];// 变量b被重新赋值,a不变化
console.log(a);//[0,1,2]
原因:
b重新赋值后,已经不指向a的地址了
七、传参时,基本类型传值,引用类型传引用。(但是重新赋值之后就不是这样了喔,原因见第六条)。
var a=10;
function fn(a){
a+=10;
}
fn(a);
console.log(a);//
按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。
var a=[0,1,2];
function fn(a){
a[3]=3;
}
fn(a);
console.log(a);//[0,1,2,3]
按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。
var a=[0,1,2];
function fn(a){
a=[0,1,2,3];
}
fn(a);
console.log(a);//[0,1,2]
函数内部给a重新赋值后,已经不指向原始值a的地址了。