在很多JavaScript编程人员的印象中,定义变量用var和不用没有区别,但实际是存在差异的:
如果使用var定义变量,那么程序会强制定义一个新变量(及时变量名相同)。
如果没有使用var定义变量,系统会有优先在当前上下文中搜索是否存在该变量。只有在该变量不存在的前提下,系统才会重新定义一个新变量。
var bb = 1;
function aa() {
bb = 2;
alert(bb);
};
aa(bb); //2
alert(bb);//2
解析:在开始定义了一个全局的bb值为1;函数内部的bb没有用var声明,则系统则从上到下搜索是否有定义该变量,正好开始定义了bb则函数内部直接把值赋给开始的bb所以都会输出2;
注意有一种特殊情况,就是如果函数的参数名和全局变量相同的话,在函数内部不写var,里面的变量会认为是形参的调用,而不会覆盖全局变量,相当于在函数的内部var 了一个bb变量,函数执行完后,函数的活动对象被销毁,也就是局部的这个bb被删除了。
var bb = 1;
function aa(bb) {
bb = 2;
alert(bb);
};
aa(bb); //2
alert(bb);//1
function Foo() {
var i = 0;
return function() {
console.log(i++);
}
}
var f1 = Foo(),
f2 = Foo();
f1();//0
f1();//1
f2();//0
(1)Function是引用类型:保存在堆中,变量f1,f2是保存在栈中;
(2)闭包:一个函数(产生新的作用域)定义的局部变量、子函数的作用域在函数内,
但是一旦离开了这个函数,局部变量就无法访问,所有通过返回子函数到一个变量f1的方法,让
f1指向堆中的函数作用域,这样可以使用局部变量i.
(3) 过程:
第一次f1() :f1=Foo()中,先执行Foo(): i = 0,return值返回给f1
(f1指向子函数 f1()=function(){…..},因为子函数没有 定义i,所以向上找到父函数定义的 i: )并执行子函数 输出i=0,再自加 i =1(覆盖了父函数Foo 的 i值);
第二次f1() : 执行的是子函数 Function(){ ..},输出的是父函数 的 i=1,再自加 i =2;
第一次f2():同第一次f1(),不同的是 f2指向堆中一个新的对象 function(){ …},所有此i非彼i,输出i=0;如果
如果再次f2(),那么和第二次f1(),一样输出i=1;