轻松理解什么是js作用域和变量、函数提升的示例

1. 作用域

作用域,顾名思义,指一个变量的作用范围。在js中有两种作用域。

  • 全局作用域

    • 全局作用域作用于整个script标签,在页面打开时创建,在页面关闭时销毁

    • 两种情况可以产生全局作用域

      • 全局声明(直接编写在script标签内的代码)
      • 在函数内部,没有声明就直接进行赋值
    • 全局作用域中有一个全局对象window,代表一个浏览器的窗口,由浏览器创建,我们可以直接使用。

    • 全局作用域中创建的变量都会作为window对象的属性保存:

var a = 10;
		/*
		 * a 变量创建出来后,会默认保存在window对象的属性中,所以说 a 也是window的属性名
		 * 在打印的时候,也可以直接使用window调用。
		 * 
		 * console.log(window.a);
		 * 打印结果:
		 * 	10
		 * 
		 * 使用window来直接调用 a 变量,所打印的结果是 10 ,这个 10 就是在创建 a 变量时初始化设置的参数值
		 *  
		 */
		console.log(window.a);

全局作用域中创建的函数都会作为window对象的方法保存

function fun(){
			console.log('我是fun函数');
		}
		/*
		 * fun()函数创建出来后,也会默认保存在window对象的属性方法中,所以说 fun() 函数也是window的属性方法,
		 * 在打印的时候,也可以直接使用window调用。
		 * 
		 * window.fun();
		 * 打印结果:
		 * 	我是fun函数
		 * 
		 * 使用window来直接调用fun()函数,所打印的结果是可以被调用,‘我是fun函数’是fun()函数代码块中的console.log()
		 */
		window.fun();
  • 局部作用域

    只在函数内部起作用,节约资源

  • 作用域链

    想要得到某一变量,但是在当前的作用域中没有定义,这种变量称为自由变量
    自由变量的值如何得到 —— 向上一层层找,按照就近原则,直到找到全局作用域,这种层级关系就是作用域链。

2. 预解析

在当前作用域中,JavaScript代码执行之前,浏览器首先会默认的把所有带var和function声明的变量进行提前的声明或者定义。

变量提升

所有变量声明提升到当前作用域的最前面,赋值不提升

console.log(num);
var num = 10;
//显示结果应为undefined

相当于执行了以下代码:(只提升声明,不提升赋值)

var num;
console.log(num);
num = 10;

函数提升

将function声明的变量进行提前的声明或者定义。
看一个例子:
以下函数先调用fun()再声明函数,会报错

fun();
var fun = function(){
	condole.log(22);
	}
//报错

相当于执行了以下代码:(只提升声明,不提升赋值)

var fun;
fun();
fun = function(){
	condole.log(22);
	}

但如果这样写,函数就能正确调用,因为fun()的声明会被提前

fun();
function fun(){
	condole.log(11);
	}
//可以正确调用函数

提升后:

function fun(){
	condole.log(11);
	}
fun();
//可以正确调用函数

让我们看更多的例子:
例1.

var num = 10;
fun();
function fun(){
	console.log(num);
	var num = 20;
}

相当于:

var num;
function fun(){
	var num;	//函数内部变量也要提升
	console.log(num);	//输出时num还没有被赋值,所以结果为undefined
	num = 20;
}		
num = 10;
fun();
}

例2.

var num = 10;
function fn(){
	console.log(num);
	var num = 20;	
	console.log(num);
}
fn();

相当于:

var num;
function fn(){
	var num;
	console.log(num);	//第一次输出undefined
	num = 20;	
	console.log(num);	//第二次输出20
}
num = 10;
fn();

**例3.(难)

f1();
console.log(c);
console.log(b);
console.log(a);
function f1(){
	var a = b = c = 9;  //var a = 9; b = 9; c = 9;
					   //b和c没有声明直接赋值,属于全局变量 
	console.log(a);
	console.log(b);
	console.log(c);
}

这里的

	var a = b = c = 9; 

相当于:

var a = 9; b = 9; c = 9;

特别注意:此处b和c没有声明,直接进行赋值,所以属于全局变量。
如果想要集体声明,应该写成:

var a = 9, b = 9, c = 9;

提升后的代码为:

//function 提升到最前面
function f1(){		
	//var a = 9; b = 9; c = 9;提升后:
	var a;
	a = b = c = 9;
	console.log(a);
	console.log(b);
	console.log(c);
}
f1();
console.log(c);
console.log(b);	//b和c是全局变量,所以可以输出
console.log(a);	//a是局部变量,此处undefined

//结果为9,9,9,9,9,undefined
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值