JS基础 -- 函数作用域

123 阅读6分钟
                /*
		 * 函数作用域
		 * 	-调用函数时,创建函数作用域,函数之完毕以后,函数作用域销毁
		 * 语法:
		 * function 函数(){
		 * 	
		 * }
		 * 这就是函数作用域,其实,就是声明一个函数。而函数作用域在没有调用前是关闭状态,
		 * 也就是说这个函数中任何语句都不会执行
		 * 
		 */
		//没有调用函数作用域
		function fun() {
			console.log('是否开启了作用域');
		}
		/*
		 * 打印结果是空白,所以在没有调用函数时,函数中的语句不会被执行,而作用域也不会被开启,
		 * 
		 * - 每调用一次函数就会创建一个新的函数作用域,他们之间是互相独立的
		 */
		function fun1(a) {
			console.log('是否开启了作用域' + a);
		}
		fun1(1);
		fun1(2);
		/*
		 * 在多次调用函数时,除了函数作用域内的语句是一样的、调用也是一样的,以外还有就是它们之间都是独立的。
		 * 不会出现互相干扰,如果函数作用域中的代码有变化。
		 * 在多次调用中,会依次执行作用域,只有当第一次执行完毕,才会执行第二次,以此类推
		 */
		/*
		 * - 在函数作用域中可以访问到全局作用域的变量(实例-01)
		 * 		在全局作用域中无法访问到函数作用域的变量(实例-02)
		 */
		//实例-01
		var a = 123;

		function fun2() {
			console.log('a = ' + a);
		}
		/*
		 * 打印结果:
		 * a = 123
		 * 
		 * 结果显示,fun2()内的console.log()可以访问外部的 a 变量;
		 */
		fun2();
		//实例-02
		//			 console.log('外部1:b = '+b);
		//			 function fun3(){
		//			 	var b = 456;
		//			 	console.log('b = '+b);
		//			 }
		//			 fun3();
		//			 console.log('外部2:b = '+b);
		/*
		 * 结果显示,‘外部1’和‘外部2’不能访问fun3()内部的 b 变量,
		 * 并且在‘外部1’和‘外部2’无法访问fun3()内部 b 变量时,控制台会报
		 * ReferenceError: b is not defined的错误信息,出现这个报错会
		 * 停止程序运行,不会继续向下执行代码;
		 * 
		 * 注意:为了下面的例子能顺利执行,这里会把fun3()注释掉
		 * 有一个可以放访问函数内的变量,那就是不使用 var 来声明(实例-03)
		 */
		//实例-03
		//不能访问函数内变量的 console.log,暂时注释掉
		//			console.log('外部3:c = ' + c);
		function fun4() {
			c = 789;
		}
		fun4();
		//可以访问函数内变量的 console.log
		console.log('外部4:c = ' + c);
		/*
		 * 打印结果:
		 * 外部4:c = 789
		 * 
		 * 结果显示,当函数内的变量没有使用时 var 创建声明变量时,
		 * 外部4 可以访问函数内的变量。但是,不能在函数创建前去访问,
		 * 因为外部3 在访问函数时,函数还没有创建内部的变量也没有被创建
		 * 
		 * 
		 * 如果出现全局变量和局部变量是同一个变量名,会有什么样的结果(实例-04)
		 * 
		 */
		//实例-04
		var d = 90;
		function fun5(){
			d = 100;
			console.log("d = "+d);
		}
		fun5();
		/*
		 * 打印结果:
		 * d = 100
		 * 
		 * 结果显示,当两个变量名相同时,在访问变量时,它会从下往上从内到外去查询这个变量。
		 * 例如实例-04:console.log要访问变量 d 时,它会从自身向上查找变量,直到查询到这个变量后直接使用,
		 * 如果在自身的作用域里没有查询到这个变量时,它会向包裹它的作用域一层一层的查询,除了和它平级
		 * 的作用域以外。只能向比自身作用域大的作用域查询。
		 * 
		 * 
		 * 相同的变量名,如果访问变量的位置是在调用函数之后,那么结果是什么?函数内的变量使用时 var 
		 * 创建变量,那么结果又是什么?(实例-05)
		 */
		//实例-05
		var e = 90;
		function fun6(){
			var e = 100;
		}
		fun6();
		//访问变量
		console.log("e = "+e);
		/*
		 * 打印结果:
		 * 	e = 90
		 * 
		 * 结果显示,当函数内的 e 变量使用 var 创建时,在调用函数下面访问 e 变量后,会直接访问到函
		 * 数上面的 e 变量,所以打印的结果就是 e = 90。
		 * 这是因为使用 var 创建变量后,只能在当前作用域有效,出了当前作用域就不能生效。如果在当前作
		 * 用域中还有很多个局部作用域时,在局部作用域中可以访问到这个当前作用域
		 * 
		 * 
		 * 注意:在不使用 var 创建变量时,所写的变量会直接成为 window的属性名,而window是最大的作用域,
		 * 所以在window内的所有局部作用域中都可以访问到这个变量。
		 * 
		 * 注意:全局作用域在js中只有一个window的作用域,而在全局作用域中的函数方法和函数可以成为局部作用域,
		 * 全局作用域中可以套用 N 个局部作用域,而局部作用域中也可以套用 N 个局部作用域
		 * 
		 * 如果全局作用域想要访问局部作用域中的变量,那么局部作用域中的变量不可以使用 var 来创建声明。
		 * 无论全局作用域中的变量是否用 var 创建声明,局部作用域可以访问全局作用域中的变量,如果全局作用域中
		 * 的变量和局部作用域中的变量是同一个名,那么局部作用域访问全局作用域的变量,需要使用window调用。
		 * (例如:全局变量是 a,在局部作用域中访问时是 window.a )
		 */
		//局部作用域访问全局作用域的变量
		//带 var 被访问
		var f = 110;
		//不带 var 被访问
		//f = 120;
		function fun7(){
			console.log('我是'+f);
		}
		fun7();
		//全局变量和局部变量是同一个名时,局部作用域想要访问全局变量
		var g = 12306;
		function fun8(){
			var g = 119;
			console.log("我到底是"+window.g);
			
		}
		fun8();
		/*
		 * fun8()这段代码有两个信息:
		 * 1.当全局变量和局部变量时同一个名时,局部作用域想要访问全局作用域的变量,需要使用 windo 来调用。
		 * 2.当全局变量和局部变量时同一个名时,局部作用域想要访问这个变量,他需要从它的位置向上查找,也就
		 *   是说它会从身边的变量中查找,如果没有它会向上一级作用域中查找,还没有继续上一级的上一级作用域
		 * 	 中查找直到查到为止。如果身边有这个变量,它会获取变量值输出完成后会继续进入下一段代码。
		 */
		/*
		 * 声明提前
		 * 在函数作用域中也有声明提前的特性
		 * 使用 var 关键字声明的变量,会在函数中所有的代码执行之前被声明
		 */
		function fun9(){
			console.log(h);
			var h = 111;
		}
		fun9();
		/*
		 * 打印结果:
		 *  undefined
		 * 
		 * 打印的结果是undefined。在 h 创建变量之前调用,h 会被提前声明,
		 * 被提前声明后因为没有给变量赋值,所以在打印的时候,结果会是undefined
		 */