js 函数形参/变量声明/函数声明优先级和arguments

function judgeOrder(animal){
    // debugger;
    console.log(animal)  // ƒ animal(){
                         //   console.log(animal)
                         // }
    animal = 'pig'
    console.log(animal)  // pig
     function animal(){
        console.log(animal)
     }
    var animal = 'cat'
    console.log(animal)  // cat
}

judgeOrder('dog')

很显然,可以这里可以看出 var animal = 'cat 这里的animal先声明,然后函数 function animal(){} 的声明覆盖了之前的变量声明。因此第一个打印出了函数。之后就是对animal进行赋值,就打印了pig,后面也一样打印了cat

那么此时,有些同学可能会奇怪传入的参数dog去哪了。那么此时,我们将 function animal(){} 这个声明注释掉看一下,发现输出如下:

function judgeOrder(animal){
    // debugger;
    console.log(animal)  // dog
    animal = 'pig'
    console.log(animal)  // pig
    // function animal(){
    //     console.log(animal)
    // }
    var animal = 'cat'
    console.log(animal)   // cat
}

judgeOrder('dog') // 如果此时未传入实参,那么第一个输出为undefined

此时,显然var animal = 'cat变量提升,但是没有进行赋值,而我们的函数形参 animal 也有值 dog,那么就会直接输出dog了,之后就是对这个animal进行重新赋值操作。

那么从结论来看,我们可以发现:
优先级: 函数形参 > 变量声明 > 函数声明,
那么相应的值就为最后赋值的变量。

这里还有一个问题就是,将arguments里的的值改变会不会影响到形参的值,将形参的值改变会不会影响到arguments里的值?

写两个简单的例子:

function judgeOrder(animal){
    console.log(animal, arguments[0])  // dog  dog
    animal = 'pig'
    console.log(animal, arguments[0])  // pig  pig 
}

judgeOrder('dog')
function judgeOrder(animal){
    console.log(animal, arguments[0])  // dog  dog
    arguments[0] = 'pig'
    console.log(animal, arguments[0])  // pig  pig 
}

judgeOrder('dog')

我们发现 arguments里对应的值与形参是相对应的,任一其中一个改变,另一个也会随之改变。这就是arguments和形参的映射机制。

但是这里提一点,就是这种模式只会在非严格模式下存在,如果在严格模式下(也就是使用了"use strict";),arguments和形参的影响是单向的

"use strict";

function judgeOrder(animal){
    console.log(animal, arguments[0])  // dog  dog
    arguments[0] = 'pig'
    console.log(animal, arguments[0])  // dog pig
}

judgeOrder('dog')

以上就是分享的所有内容啦,如果哪里有错,欢迎指出并讨论,谢谢!

上一篇:C#|更改序列化节点Name名及XElement返序列化


下一篇:JavaScript继承