JavaScript_预解析及作用域 ——恋天小结

预解析

JavaScript引擎在对JavaScript代码进行解释执行之前,会对JavaScript代码进行预解析,在预解析阶段,会将以关键字var和function开头的语句块提前进行处理。

当变量和函数的声明处在作用域比较靠后的位置的时候,变量和函数的声明会被提升到作用域的开头

函数提升
func();
function func(){
	函数体;
};

由于JavaScript的预解析机制,上面的代码就等效于:

function func(){
	函数体;
};
func();

变量提升
alert(a);
var a = 1;

由于JavaScript的预解析机制,上面这段代码,alert出来的值是undefined,如果没有预解析,代码应该会直接报错a is not defined,而不是输出值,不是说要提前的吗?那不是应该alert出来1,为什么是undefined?

上面的代码就等效于:

var a;
alert(a);
a = 1;
函数同名的情况

变量和函数同名,函数优先级高,变量不会预解析

func1();
function func1(){
console.log('This is func1');
}

func1();
function func1(){
console.log('This is last func1');
}

输出结果为:
This is last func1
This is last func1
原因分析:由于预解析机制,func1的声明会被提升,提升之后的代码为:

function func1(){
console.log('This is last func1');
}

func1();
func1();

同名的函数,后面的会覆盖前面的,所以两次输出结果都是This is last func1。

变量和函数同名
alert(foo);
function foo(){}
var foo = 2;

当出现变量声明和函数同名的时候,只会对函数声明进行提升,变量会被忽略。所以上面的代码的输出结果为
function foo(){}
我们还是来吧预解析之后的代码展现出来:

function foo(){};
alert(foo);
foo = 2;

再来看一种

var num = 1;
function num () {
alert( num );
}
num();

代码执行结果为:
Uncaught TypeError: num is not a function

直接上预解析后的代码:

function num(){
alert(num);
}

num = 1;
num();

预解析是分作用域的

提升原则是提升到变量运行的环境(作用域)中去。

function showMsg()
{
var msg = 'This is message';
}
alert(msg); // msg未定义

还是直接把预解析之后的代码写出来:

function showMsg()
{
var msg;
msg = 'This is message';
}
alert(msg); // msg未定义
函数表达式并不会被提升
func();
var func = function(){
alert("我被提升了");
};

这里会直接报错,func is not a function,原因就是函数表达式,并不会被提升。只是简单地当做变量声明进行了处理,如下:

var func;
func();
func = function(){
alert("我被提升了");
}

作用域

作用域链

只有函数可以制造作用域结构, 那么只要是代码,就至少有一个作用域, 即全局作用域。

凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。

将这样的所有的作用域列出来,可以有一个结构: 函数内指向函数外的链式结构。就称作作用域链。
例如:

function f1() {
	function f2() {
	}
}

var num = 456;
function f3() {
	function f4() { 
	}
}

绘制作用域链的步骤:
看整个全局是一条链, 即顶级链, 记为 0 级链

看全局作用域中, 有什么成员声明, 就以方格的形式绘制到 0 级练上

再找函数, 只有函数可以限制作用域, 因此从函数中引入新链, 标记为 1 级链

然后在每一个 1 级链中再次往复刚才的行为
在这里插入图片描述
在这里插入图片描述

隐式全局变量

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值