Day2:写出执行结果,并解释原因(函数参数、严格模式、ES6)

112 阅读3分钟

Day2:写出执行结果,并解释原因

image.png

function side(arr) {
  arr[0] = arr[2];
}
function a(a, b, c = 3) {
  c = 10;
  side(arguments);
  return a + b + c;
}
a(1, 1, 1);
// 写出执行结果,并解释原因

答案

12

解析

arguments c 的值还是 1 不会变成 10, 因为 a 函数加了默认值,就按 ES 的方式解析,ES6 是有块级作用域的,所以 c 的值是不会改变的

深度剖析

ES6 环境中 函数参数有一个独立的作用域,独立于函数内部与外部,我们在给函数初始化默认指时候默认会开启ES编译模式, 函数参数传递时,只是简单的值拷贝,当我们传递简单数据类型时Arguments 与 函数参数将只是值的拷贝,改变Arguments 的值,将不会影响参数 的值,我们来看一下下面的例子:


function side(arr) {
    arr[0] = arr[2];
}
function a(a, b, c = 3) {
    c = 10;
    console.log(arguments) //[Arguments] { '0': 1, '1': 1, '2': 2 }
    side(arguments);
    console.log(arguments) // [Arguments] { '0': 2, '1': 1, '2': 2 }
    console.log(c)  // 10
    return a + b + c;
}

console.log(a(1, 1, 2));  // 12

image.png

从上面我们可以看出当我们修改 argument的时候并不会影响 c 的值 我们看看当我们不设置初始化默认值 && 不开启严格模式的情况下,修改argument 值的变化


console.log("------ 我们在 不使用函数默认值 使修改 argument ---");
function a1(a) {
    // 修改 argument

    arguments[0] = 100;
    console.log(a);  // 100
}
a1(12); // a =100 

image.png 此时 a 的值 变成了 100

开启严格模式 a的 变化(基本数据类型)

"use strict"
console.log("------ 开启严格模式修改 ---");
function a2(a) {
    // 修改 argument

    arguments[0] = 100;
    console.log(a);
}
a2(12);  // 12

image.png 当我们开启严格模式时,arguments 值 被修改时 a 的值没有影响 ,此时a 的值只是对arguments做了简单的拷贝

未开启严格模式 a的 变化(引用数据类型)


console.log("------ 非严格模式 修改 arguments 的值  ---");

function fun(obj) {
    console.log(arguments[0], obj)  // { a: 100 } { a: 100 }
    arguments[0].a = 12
    console.log(obj)   // { a: 12 }
    obj.a = 100
    console.log(arguments)   // [Arguments] { '0': { a: 100 } }
    console.log(arguments[0] === obj)  // true
}

fun({ a: 100 })

image.png 在未开启严格模式时 arguments 与 函数参数是进行绑定的,修改 arguments 会修改 参数的值,修改参数的值同样会是修改 arguments 中的值, 并且 引用的是同一块地址

开启严格模式 a 的 变化(引用数据类型)

"use strict"
console.log("------ 严格模式 修改 arguments 的值  ---");

function fun(obj) {
    console.log(arguments[0], obj)  // { a: 100 } { a: 100 }
    arguments[0].a = 12
    console.log(obj)   // { a: 12 }
    obj.a = 100
    console.log(arguments)   // [Arguments] { '0': { a: 100 } }
    console.log(arguments[0] === obj)  // true
}

fun({ a: 100 })

image.png 在严格模式下,我们在传入引用类型时,在与非严格模式下的结果是一致的,因为严格模式下只是对值的简单拷贝, 引用类型拷贝,只拷贝地址,所有arguments指向的地址与参数指向的地址一致,所有修改的时候会相互影响。

使用参数默认值

结果与开启严格模式相同 这里就不在测试了,想测试的可以自行测试。