JavaScript难点——变量提升和函数提升(二)

来源:互联网 发布:red hat linux安装 编辑:程序博客网 时间:2024/06/04 18:58

前端菜鸟的成长之路


先上代码,(据说是一道面试题)

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

分析如下:

var a;               //变量声明提升console.log(a);      //undefineda = 1;               //变量赋值 全局变量a 被赋值 1;function b() {    function a() {}  //函数声明提升    a = 10;          //虽然在函数作用域内,但没有用var声明 属于全局变量 a被赋值10    return;          //返回 不在执行后续代码    console.log(a)   //若无return 输出10}b();console.log(a)       //10

感觉良好地打开控制台面板,结果就 …

(什么情况?我日……出江花红胜火 春来江水绿如蓝。)

(不行,要冷静,要克制,哪里出了问题了呢?)

大脑短暂的断线后,我发现了一个疑点,就它

function a() {}  //函数声明提升

(按照之前的分析,有它没它应该没有区别啊,难道不是么?)

(肯定不是啊?出题人有病啊,放句没用的代码。踩坑了吧!一定是它的问题。)

尝试注释掉这行代码后发现,果然是它,它改变了b()函数中a的作用域,a变成了局部变量,WHY?

琢磨加百度之后,又发现了一个新的知识点一个名称如何进入一个作用域作用域中的名称解析顺序

在JavaScript中,一个名称(name)进入一个作用域(scope)一共有四种方式:

  1. 语言自身定义(Language-defined): 所有的作用域默认都会包含this和arguments。

  2. 函数形参(Formal parameters): 函数有名字的形参会进入到函数体的作用域中。

  3. 函数声明(Function decalrations): 通过function foo() {}的形式。

  4. 变量声明(Variable declarations): 通过var foo;的形式。

上面列出的顺序就是他们解析的顺序。总的来说,如果一个名称已经被定义了,他绝不会被另一个拥有不用属性的同名名称覆盖。这就意味着,函数声明比变量声明具有更高的优先级。但是这却不意味着对这个名称的赋值无效,仅仅是声明的部分会被忽略而已。

回到我们上面的代码

function a() {}  //函数声明提升 名称a进入作用域 成为局部变量

(bingo!!! )(哦耶)

再次对代码分析

var a;               //变量声明提升console.log(a);      //undefineda = 1;               //变量赋值 全局变量a 被赋值 1;function b() {    function a() {}  //函数声明提升 名称a进入作用域 成为局部变量    a = 10;          //a被赋值10    return;          //返回 不在执行后续代码    console.log(a)   }b();console.log(a)       //1

结束

原创粉丝点击