1、函数作用域
1、两个不同的script标签,先执行完前一个全部代码,并且后面的script能用前面的script变量
2、在同一个script里面按从上到下执行顺序是不可理的
/*
在同一个作用域里面(代码的执行步骤):
1、定义
var a(定义变量)
函数的定义(有名函数的定义)
2、执行(除了定义都是执行,从上往下)
*/
alert(a);//undefind
var a = '楠楠';
2、新的作用域和作用域链
新作用域:
每遇到新的作用域,就会开始新的定义和执行步骤,在新的作用域执行完毕后再回到上级作用域继续执行;
作用域链:
在执行时遇到变量时就会在当前作用域寻找,如果没有找到,就会向父级寻找,如果一直没有找到,就会返回undefined(注意:undefined是找到了,但是没有赋值),父级不能向子级寻找变量
var name = '纷纷';
function fn(){
console.log(name); //undefined
var name = '楠楠';
console.log(name); //楠楠
}
fn();
3、闭包
/*
闭包:
inter函数能够持久保存自己定义时所处的环境,在哪里调用,都会记住自己所处的环境,
并且把声明的变量和环境封装成一个封闭的环境,我们称之为‘闭包’;
一个函数也是一个闭包
*/
function outer(){
var a = 3;
function inter(){
console.log(a);
}
return inter;
}
var fna = outer();//inter
fna();
闭包的性质:
1、每次重新引用函数的时候,闭包都是全新的;
最常用的闭包:
<style>
#box{
width: 500px;
margin: 100px auto;
}
#box p{
width: 100px;
height: 100px;
background-color: #ccc;
margin: 10px;
float: left;
}
</style>
<body>
<div id='box'>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
</div>
</body>
<script>
/* 案例1 (利用函数来存变量)*/
var aP = document.querySelectorAll('p');
for(var i=0;i<aP.length;i++){
(function (m) {
aP[m].onclick = function () {
alert(m+1);
}
})(i);
}
/* 案例2 (定义新的属性来存变量)*/
var aP = document.querySelectorAll('p');
for(var i=0;i<aP.length;i++){
aP[i].index = i+1;
aP[i].onclick = function(){
alert(this.index);
}
}
</script>
运行结果图:(实现点击对应的方格弹出对应的数字)