javascript_作用域和闭包

作用域概述

在函数内定义的变量不能从函数之外的任何地方取得,变量仅仅在该函数的内部有定义。JS没有块级作用域,能封闭作用域的只有一个东西:函数

局部变量和全局变量
  • 定义变量时不写var,变量将自动变为全局变量
  • 当遇见一个变量时,JS引擎会从其所在的作用域依次向外层查找,查找会在找到第一个匹配的标识符的时候停止。在多层嵌套的作用域中可以定义同名的标识符,这将发生“遮蔽效应”。
  • 函数的参数是一个局部变量
  • 函数可以内嵌函数,和变量同样的道理。内嵌函数是只能在外层函数中调用的,离开外层函数,将不能被调用。
//案例1
function fn(){
	var a=1; //定义在一个函数内部的变量,局部变量,只有在函数里面有定义。
	console.log(a); //1
}
console.log(a);  //报错
//案例2
var a=1; //全局变量
function fn(){
	console.log(a);
}
fn();//1
console.log(a);//1
//案例3
function outer(){
	var a=1;// a的作用域是outer范围
	inner();
	function inner(){
	 var b=2; //b的作用域是inner范围
	 console.log(a);//能够输出1
	 console.log(b);//能够输出2
	}
}
outer();
console.log(a);//报错
//案例4
//同名变量多层嵌套,会发生遮蔽现象
var a=1;
function fn(){
	var a=5;// 把外层的a给屏蔽了。
	console.log(a);//5
}
fn();
console.log(a);//1

//案例5
var a=1;//全局变量
var b=2;//全局变量
function outer(){
	var a=3; //遮蔽了外层的a,a局部变量
	function inner(){
		var b=4; //遮蔽外层的b,b局部变量
		console.log(a);  // 输出语句1   输出3  a现在在当前层找不到定义,去上一层寻找
		console.log(b);  //输出语句2    输出4
	}
	inner();  //执行函数,控制权交个inner()
	console.log(a);  //输出语句3   输出 3
	console.log(b);  //输出语句4   输出4   b现在在当前层找不到定义的,去上一层寻找
}
outer(); //执行函数,控制器交给outer
console.log(a);  //输出语句5   输出1  全局变量
console.log(b);  //输出语句6  输出 2   全局变量

//案例6
// 不写var ,声明的变量即为全局变量
function fn(){
	a=1;
}
fn();
console.log(a);//1

//案例7
//函数的参数,会默认定义为这个函数的局部变量

//案例8
//全局变量的作用  
// 1:通信  共同操作同一个变量 
var num=0;
function add(){
num++;
}
function remove(){
num--;
}
//案例9
//2. 累加
var num=0;
function fn(){
	num++;
	console.log(num);
}
//案例10
//函数的定义也有作用域
function fn(a,b){
	return fn2(a)+fn2(b);
	function fn2(m){
		return Math.pow(m,2);
	}
}
fn(3,4);
fn2(4);//无法单独运行,报错,全局作用域下,没有函数名为fn2的函数

作用域链:变量会逐层寻找,funciton层 —> 全局变量层 ----> 无定义报错
函数的参数,会默认定义为这个函数的局部变量

闭包

//案例1
function outer(){
	function inner(){
	console.log("outer");
	}
}
inner();// 报错  outer函数外面没有inner的定义
//案例2  经典闭包
function outer(){
	var a=1;
	function inner(){
	console.log(a);
	}
	return inner;//相当于return function inner(){console.log(a);}  returninner函数定义
}
var inn=outer();
inn();  // 执行inn,全局作用域下没有a的定义,但是函数闭包,能够把定义函数的时候的作用域一起记住,能够输出1.
//详细说明:inner函数你能够持久保存自己定义时所处的环境,并且及时自己在其他的环境被调用的时候,依然可以访问自己定义时所处环境的值


//案例3
var inner; //定义inner全局
function  outer(){
	var a=1;
	inner=function(){
	alert(a);
	}
}
//执行outer ,相当于 将inner的值变成function(){alert(a)}; 这个函数将有闭包
var a=300;
inner();//a=1;  一个函数在执行的时候,找闭包里面的变量,不会考虑当前的作用域

//案例4
function outer(x){
	function inner(y){
		console.log(x+y);
	}
	retrun inner;
}
//
var inn=outer(3);
inner(5);//3+5=8

闭包: 函数可以把自己内部的语句和自己声明时所处的作用域一起封装成一个密闭环境,我们称为“”闭包“”(Clousures).
每个函数都是闭包,每个函数天生都能够记忆自己定义时所处的作用域环境。

闭包的性质
  • 每次重新引用函数的时候,闭包是全新的。
//案例1

function outer(){
var count=0;
	function inner(){
	count++;
	console.log(count);
	}
	return inner;
}
var inn1=outer();
inn1();//1
inn1();//2
inn2();//1  重新计数
//案例2
function fun1(m,n){
	function fun2(m){
		alert(m+n);
	}
	return fun2;
}
var f=fun1(3,4);
f(6);  //6+4=10
发布了49 篇原创文章 · 获赞 3 · 访问量 5120

猜你喜欢

转载自blog.csdn.net/weixin_43487066/article/details/89918163
今日推荐