一、变量作用域
变量根据作用域的不同分为两种:全局变量
和局部变量
1、函数内部可以使用全局变量
2、函数外部不可以使用局部变量
3、当函数执行完毕,本作用域内的局部变量会销毁
二、闭包
闭包指有权访问
另一个函数作用域中变量
的函数
(闭包是一个函数)
function fn(){
var num=10;
function fun(){
console.log(num);//10 fun这个函数作用域 访问了另外一个函数 fn里面的局部变量num
}
fun();
}
fn();
三、闭包的作用
延伸变量的作用范围
fn外部的作用域可以访问fn内部的局部变量
function fn(){
var num=10;
// function fun(){
// console.log(num);
// }
//return fun;
return function(){
console.log(num);//10
}
}
var f=fn();
f();
//类似于
//var f=function(){
//console.log(num);
//}
var f= function fun(){
console.log(num);
}
四、闭包案例
1、利用闭包的方式得到当前li的索引号
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<script>
var lis=document.querySelector(".nav").queryselectorAll("li");
for(var i=0;i<lis.length;i++){
//利用for循环创建了四个立即执行函数
//立即执行函数也是闭包因为立即执行函数里面的任何一个函数都可以使用它的i这个变量
(function(i){
console.log(i);
lis[i].onclick=function(){
console.log(i);
}
})(i);
}
</script>
缺点:立即函数里的i变量,当函数执行完毕后i应当销毁,但是里面的点击事件会用到i 所以等到点击事件结束后才会销毁,不点击就不会销毁,会占用内存(内存泄漏)。
2、 定时器中的闭包
<ul class="nav">
<li>1</li>
<li>2</li>
<li>3</li>
<script>
//3秒之后,打印所有li元素内容
var lis=document.querySelector(".nav").queryselectorAll("li");
for(var i=0;i<lis.length;i++){
(function(i){
setTimeout(function){
console.log(lis[i].innerHTML);
},3000)
})(i);
}
五、递归
什么是递归:如果一个函数在内部可以调用其本身,那么这个函数就是递归函数(函数内部自己调用自己)
function fn(){
fn(); //类似死循环
}
fn();
递归避免出现这种情况,所以必须加退出条件return
var num=1;
function fn(){
console.log(num);
if(num==6){
return; //递归里面必须加退出条件
}
num++;
fn();
}
fn();
六、利用递归遍历数据
var data=[{
id=1,
name:"家电",
goods:[{
id:11,
gname:"冰箱"
},{
id:12,
gname:"洗衣机"
}]
},{
id:2,
name:"服饰"
}] ;
//输入id号,就可以返回数据对象
//利用forEach遍历里面的每一个对象
function getID(json,id){
json.forEach(function(item){
if(item.id=id){
console.log(item);
//想得到里层的数据 11 12 可一利用递归函数
//里面应该有goods这个数组并且数组长度不为0
}else if(item.goods&&item.goods.length>0){
getID(item.goods,id);
}
})
}
getID(data,1);
getID(data,2);
getID(data,11);