[转载自https://www.cnblogs.com/yesw/p/3999668.html]
Js语句是怎么解析的(同一个作用域)
首先会全局查找(预解析)var, function提升其优先级
alert(a); var a = 1;
上面的两行代码是这么解析的:
var a; alert(a); a = 1;
所以结果是undefined
1.所有的变量在正式代码运行之前,都是undifined
2.所有的函数在正式运行之前, 都是函数块(域)
其次解读代码:
一些表达式(+-=*%!等)
表达式可以修改预解析的值
函数调用
遇到函数域或者一个新的域 又会重复做首先, 其次的动作
作用域链查找规则:自上而下(一个或多个sript), 由里到外查找(函数中)
一些例子
var a = 1; function foo(){ alert(a) ; var a = 2; } foo(); alert(a);
var a = 1; function foo(){ alert(a); a = 2; } foo(); alert(a);
var a = 1; function foo(a){ alert(a); a = 2; } foo(); alert(a);
var a = 1; function foo(a){ alert(a) ; a = 2; } foo(a); alert(a);
if和for语句都不会生成新的作用域, FF下有这样一个bug-----------不可以对if语句下的函数进行预解析,所以不要在if和for语句中定义变量或者函数
alert(a);//undefined alert(fun);//FF下报错,其他浏览器会弹出fun整个函数 if(true){ var a = 1; function fun(){ alert(2); } }
经典问题再现:
//三个input
var obj = document.getElementsBytagName("input"); for(var i = 0; i < obj.length; i++){ alert(i);; obj[i].onclick = function(){ obj[i] .style.background = "red"; } }
为什么 i 的值是3 而不是0,1,2?
for语句是不存在块级作用域, 按照JS的与解析机制, 当for语句执行完毕之后, 再解析onclick函数的块级作用域, 此时for循环完毕, 所以onclick函数内的obj[3]是undfined.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
闭包相关问题
了解JS垃圾回收机制: 函数内部定义的变量在函数调用后, 被释放回收; 假如函数内部还定义了函数, 并且引用了变量, 此时这些变量不会被回收;
闭包定义: 函数嵌套函数, 内部函数引用外部函数的变量或者参数, 这些变量或者参数不会被收回
作用:
1.希望变量长期驻扎在内存中
2.避免全局变量污染
3.私有成员存在
用法:
1.模块化代码
var foo = (function(){ var a = 1; function f1(){ a++; alert(a); } function f2(){ a++; alert(a); } return { a:f1; b:f2 } })();
foo.a();//1
foo.a();//2
2.在循环中找到对应元素的索引(解决上面的经典问题)
//方法一 var obj= document.getElementsByTagName('input'); for(var i = 0; i< obj.length; i++>){ ( function(i){ obj[i].onclick = function(){ obj[i].style.background = "red"; } })(i); } //方法二 var obj = document.getElementsByTagName('input'); for(var i = 0; i < obj.length; i++){ obj[i].onclick = (function(i){ return function(){ obj[i].style.background = "red"; } })(i); }