JS中关于函数名与变量名重名、作用域链、预解析的问题

一、预解析

1.先说js代码的预解析问题,js和许多其他语言不同,它在执行之前会预解析代码,意思就是变量声明函数声明提升,值得注意的是函数声明提升比变量声明提升的优先级高,先来看几个例子:

console.log(a);//打出的是 undefined
var a=1;
console.log(a);//打出的是 1

上面的代码与下面的代码等价:

var a;
console.log(a);
a=1;
console.log(a);

意思就是变量(函数)声明会提升到它的作用域的最上面,而变量的赋值还是在原来的位置。


2.当函数名和变量名重名时:我刚刚说函数声明提升比变量声明提升的优先级高,是什么意思呢?看下面的例子:

function a() {};
var a;
console.log(a);

上面这三行代码无论顺序是怎样的,打印出的结果都是函数a,原因就是函数的声明提升会比变量的声明提升优先级高。但是我改动一下上面的代码就完全不一样了:

var a=1;
function a() {};
console.log(a);//打印 1

那么为什么改动一下就变成打印1了呢?我们来仔细分析一下js预解析的结果:

function a() {};//首先函数声明优先级最高
var a;//然后是变量
a=1;//然后给a赋值,此时a已经被赋值成一个number类型了
console.log(a);//所以打印出的是 1

3.说到函数的预解析,这里有一个易错点,看下面的代码:

	f1();//报错
	console.log(f1);//undefined
    var f1=function () {
        console.log(a);
        var a=10;
    };

上面的f1()根本调用不了,会报错,它预解析之后的结果是这样的:

	var f1;//变量声明提升
	f1();//报错
	console.log(f1);//undefined
    f1=function () {
        console.log(a);
        var a=10;
    };
    /*用一个变量去接收一个函数时,预解析只会让变量声明提升,当代码执行到它原来的位置时变量才被赋值
    成一个函数*/

二、作用域链

这个大家都懂吧,作用域就是指变量的使用范围,除了函数以外,其他的任何位置用var定义的变量都是全局变量。注:js没有块级作用域

作用域链就是当一条执行语句用到某一个变量时,会先在本级作用域去找这个变量,如果没有找到,就到上一级作用域里去找,以此类推。

三、总结

看到这里,你是不是觉得比较简单,那么来做一道题吧:

var a = 1;
function b(){
    a = 10;
    return;
    function a(){
        console.log(a);
    }
}
b();
console.log(a);

用到我刚才讲到知识,你觉得打印出的答案是多少呢?

如果你觉得答案是10,那么恭喜你,答错了!

有很多人会觉得进入函数b之后,让a赋值为10,之后就return了,所以结果是10。但是却忘了函数声明提升与作用域的问题。

我们先写出预解析的结果:

function b(){
	function a(){
        console.log(a);
    }
    a = 10;
    return;
}
var a;
a=1;
b();
console.log(a);

这是代码预解析的结果,如果你不知道这个是怎么来的,那你再重新看看上面的讲解吧

从预解析的结果看,执行函数b时,函数b内有一个函数名为a的函数声明,且函数a下面有一个变量名为a的变量,且赋值为10。首先看函数a,由于在执行函数b的时候,并没有调用函数a,因此函数a并没有起作用;但是执行到a=10的时候,首先查找变量a的地址,从系统内存中开始按照作用域链查找,由于作用域链的查找顺序是由里向外的,故要先从函数b里面开始查找,在查找的过程中,发现函数b中已经声明了一个函数名为a的函数,所以查找到函数名为a的函数后,这里便不再往外查找,直接将a=10赋值给了函数名为a的这个函数对象,而外部的a不受影响。

如果对这个结果有什么问题,欢迎在下方留言,看到后会回复。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值