一、 js没有块级作用域(可以自己闭包或其他方法实现),只有函数级作用域,函数外面的变量函数里面可以找到,函数里面的变量外面找不到。
var a=10;function fn(){ console.log(a); //10}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);//10console.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);//20}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);//10 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);//10
按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。
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的地址了。