美文网首页
待整理01-JS 形参与变量声明和函数声明同名怎么办?

待整理01-JS 形参与变量声明和函数声明同名怎么办?

作者: love丁酥酥 | 来源:发表于2018-03-18 01:12 被阅读9次

1. 简介

前两天遇到一道很有意思的题目,乍看起来是一道考声明提升和变量提升的题目的,但事实上还包含了更多的知识点。下面我们一起来看一下。

function f(a) {
    console.log(a);  // function a() {}
    var a = 2;
    function a() {}
    console.log(a);  // 2
}

f(1);

2. 详细讲解

这道题目初看上去很简单。首先,你要能解答如下问题:

function f(b) {
    console.log(a);  // function a() {}
    var a = 2;
    function a() {}
    console.log(a);  // 2
}

f(1);

如果,形参与函数内部的变量声明或者函数声明不同名,这道题很容易解答。如果你不会,可以看一下这两篇文章。JS入门难点解析2-JS的变量提升和函数提升JS入门难点解析5-变量对象,我剖析了函数声明和变量声明的表现和原理。

但是这里很特别,这题除了考察函数声明,变量声明的提升以外,还考察了同名变量和同名形参的覆盖问题,这种情况该如何分析呢?

我们要分成三种情况,第一种传入变量是具体的值,第二种传入变量是函数声明,第三种传入变量是函数赋值的变量。

2.1 传入变量是具体的值

这种就是题目所述的情况。我们再试着分解题目。看下面两代码:

function f(a) {
    console.log(a);  // 1
    var a = 2;
    console.log(a);  // 2
}

f(1);
function f(a) {
    console.log(a);  // function a() {}
    function a() {}
}

f(1);

这是什么原因呢?试着回忆一下,函数进入执行流程的步骤是什么?首先是执行环境进行准备工作,这一阶段,变量对象会包括:函数的所有形参 (如果是函数上下文),函数声明,变量声明。我们已经比较过函数声明和变量声明内部与之间的优先级,当这些变量同名时。
1. 函数声明 替换 变量声明
2.后面的函数声明替换前面的函数声明
3.后面的变量声明无效
此外,从这里我们可以看到,f(1)的其实等同于如下效果:

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

等于在函数内部第一行执行了一个变量赋值,大家看一下,是不是这样变化以后,结果仍然是遵循之前的规则。

2.2 传入的是函数声明

如下:

function f(a) {
    console.log(a);  // ƒ a() {  console.log('outer'); }
    var a = 2;
    function a() {}
    console.log(a);  // 2
}
f(a);
function a() {
    console.log('outer');
}
function f(a) {
    console.log(a);  // function a() {}
    var a = 2;
    console.log(a);  // 2
}
f(a);
function a() {
    console.log('outer');
}

可以看出,函数f内部等同于如下效果:

function a() {
    console.log('outer');
}
console.log(a);
var a = 2;
function a() {}
console.log(a);

这样看,是不是一目了然呢?

2.3 传入函数赋值的变量

进一步思考,如果这是一个赋值为函数的变量呢?

function f(a) {
    console.log(a);  // function a() {}
    var a = 2;
    function a() {}
    console.log(a);  // 2
}
f(a);
var a = function b() {
    console.log('outer');
}

聪明的你应该猜到了,是的,效果就等同于如下:

var a = function b() {
    console.log('outer');
}
console.log(a);  // function a() {}
var a = 2;
function a() {}
console.log(a);  // 2

3. 总结

综上,其实传参这一步,我们可以将其转化到函数内的第一行,改写为变量声明赋值或者函数声明。当这些变量同名时,应用的规则仍然是以下三条:
当这些变量同名时。
1. 函数声明 替换 变量声明
2.后面的函数声明替换前面的函数声明
3.后面的变量声明无效

相关文章

  • 待整理01-JS 形参与变量声明和函数声明同名怎么办?

    1. 简介 前两天遇到一道很有意思的题目,乍看起来是一道考声明提升和变量提升的题目的,但事实上还包含了更多的知识点...

  • 形参与变量声明和函数声明同名(自测原型链)

    题目来源:https://www.cnblogs.com/simonbaker/p/4237970.html九道题...

  • js-预编译

    函数声明整体提升变量 声明提升 function 创建AO对象(Active Object) 寻找形参与变量声明,...

  • 文件作用域

    在JavaScript文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会互相影...

  • 框架-模块化、API

    文件作用域 在 JavaScript 文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和...

  • 关于JS函数声明和变量同名问题

    之前学习JS的变量声明前置和函数声明的相关内容时,忘记讨论一个互相影响的问题了,这里特地补充一下。 即JavaSc...

  • 变量提升

    1.先把变量声明和函数声明提升到作用域的顶部2.在同一个作用域下,同名的函数提升会覆盖变量提升,不管二者谁先声明3...

  • 2018-08-10

    声明 声明的语法: 格式:声明说明符:声明符; 声明的格式 规则 举例; 储存类型: 变量 函数 形参 等的类型说...

  • 引用类型

    变量提升和函数声明提升   函数声明提升就是把函数声明提升到函数声明所在作用域中(或者说一个函数体内)的顶端,变量...

  • 变量函数提升

    变量被提升 因为变量声明和函数声明会被解释为: 函数被提升 声明式函数会自动将声明放在前面并且执行赋值过程,而变量...

网友评论

      本文标题:待整理01-JS 形参与变量声明和函数声明同名怎么办?

      本文链接:https://www.haomeiwen.com/subject/jfbsqftx.html