// 基本类型
let foo = 5;
// 定义一个貌似可以改变基本类型值的函数
function addTwo(num) {
num += 2;
}
// 和前面的函数一样
function addTwo_v2(foo) {
foo += 2;
}
// 调用第一个函数,并传入基本类型值作为参数
addTwo(foo);
// Getting the current Primitive value
console.log(foo); // 5
// 尝试调用第二个函数...
addTwo_v2(foo);
console.log(foo); // 5
addTwo和addTwo_v2函数调用时,JavaScript会检查标识符foo的值,从而准确无误的找到第一行实例化变量的声明语句。 找到以后,JavaScript将其作为参数传递给函数的形参。
在执行函数体内语句之前,JavaScript会将传递进来的参数(基本类型的值)复制一份,创建一个本地副本。这个副本只存在于该函数的作用域中,我们能够通过指定在函数中的标识符访问到它(addTwo中的num,addTwo_v2中的foo)。
接下来,函数体中的语句开始执行: 第一个函数中,创建了本地num参数,num的值加2,但这个值并不是原来的foo的值。
第二个函数中,创建了本地参数foo,并将它的值加2,这个值不是外部foo的值。在这种情况下,外部的foo变量不能以任何方式被访问到。这是因为JavaScript的词法作用域(lexical scoping)所导致的变量覆盖,本地的变量foo覆盖了外部的变量foo。欲知详情,请参阅闭包。 综上所述,函数中的任何操作都不会影响到最初的foo,我们操作的只不过是它的副本。