作用域
没有块级作用域
if(true){
var name='zhangsan'
}
console.log(name)//'zhangsan'
只有全局和函数作用域
var a=100;
function fn(){
var a=200;
console.log('fn',a)
}
console.log('global',a)
fn()
作用域链
var a=100
function fn(){
var b=200
//当前作用域没有定义的变量,即'自由变量'
console.log(a)
console.log(b)
}
fn()
var a=100;
function F1(){
var b=200;
function F2(){
var c=300;
console.log(a); //a是自由变量
console.log(b); //b是自由变量
console.log(c);
}
F2()
}
F1();
- 注意:函数的父级作用域是函数定义时候的作用域,不是函数执行时候的作用域,也就是说那个作用域定义了这个函数,这个函数的父级作用域就是谁,跟函数执行没有关系,函数自由变量要到父级作用域中找,就形成了作用域链。
闭包
1、实际开发中闭包的应用:封装变量,收敛权限
function F1(){
var a=100;
//返回一个函数(函数作为返回值)
return function(){
console.log(a);//自由变量,父作用域寻找
}
}
//f1得到一个函数
var f1=F1();
var a=200;
f1();//100
闭包使用场景
函数作为返回值
函数作为参数传递(函数自由变量要到父级作用域中找)
function F1(){
var a=100;
return function(){
console.log(a);
}
}
var f1=F1();
function F2(fn){
var a=200
fn();//(自由变量要到声明定义时的父作用域中找,和执行的作用域没有关系)
}
F2(f1);//100
练习题
练习题1、说一下对变量提升的理解
①变量的定义
②函数的声明(注意和函数表达式的区别)
练习题2、说明this几种不同的使用场景
参考上文**this**
练习题3、创建10个`<a>`标签,点击的时候弹出来对应的序号
var i;
for(i=0;i<10;i++){
(function(i){
var a=document.createElement('a');
a.innerHTML=i+'<br>';
a.addEventListener('click',function(e){
e.preventDefault();
alert(i);
})
document.body.appendChild(a);
})(i);//相当于创建了10个函数
}
练习题4、如何理解作用域
自由变量
作用域链,即自由变量的查找
闭包的两个场景
练习题5、实际开发中闭包的应用
//闭包实际应用中主要用于封装变量,收敛权限
function isFirstLoad(){
var _list=[];
return function(id){
if(_list.indexOf(id)>=0){
return false;
}else{
_list.push(id);
return true;
}
}
}
//使用
var firstLoad=isFirstLoad();
firstLoad(10);
firstLoad(10);
firstLoad(20);
//你在 isFirstLoad 函数外面,根本不可能修改掉_list的值
网友评论