当前位置:嗨网首页>书籍在线阅读

04-函数参数

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

6.3 函数参数

现在已经知道如何调用一个函数并在函数外获得它的返回值,那么如何给函数内部传值呢?给函数调用传值的主要途径称为函数参数。参数是指那些在函数调用结束后就不再存在的变量。现在我们来看看这个函数,它有两个数字作为参数,返回这两个数字的平均值。

function avg(a, b) {
   return (a + b)/2;
}

在这个函数声明中, ab 称为形参。当函数被调用时,形参会被赋值然后变成实参。

avg(5, 10);                  // 7.5

在这个例子中,形参 ab 分别被赋值 510 ,成为实参(跟变量赋值很相似,特殊的是它们在函数内)。

初学者很容易犯迷糊的一个概念是:参数只存在于函数内部,即使它们在函数外有相同变量的名字。看下面这个例子:

const a = 5, b = 10;
avg(a, b);

这里的变量 ab 是分开的,这与函数 avg 参数中的 ab 是完全不同的,即使它们的名字一样。在调用函数时,函数的参数只会接收传入的值,而不是变量本身。再看以下代码:

function f(x) {
    console.log('inside f: x=${x}');
    x = 5;
    console.log('inside f: x=${x} (after assignment)');
} 
let x = 3;
console.log('before calling f: x=${x}');
f(x);
console.log('after calling f: x=${x}');

运行这个例子,你会看到:

before calling f: x=3
inside f: x=3
inside f: x=5 (after assignment)
after calling f: x=3

这里需要理解的是:在函数中给x赋值并不会影响到函数外的变量x,因为它们是两个不同的实体,只是名字碰巧相同而已。

不论何时给函数中的参数赋值,都不会影响任何函数外的变量。不过,如果在函数内修改了一个对象类型的变量,那么这个改动在函数外也会生效:

function f(o) {
    o.message = 'set in f (previous value: '${o.message}')';
}
let o = { 
    message: "initial value"
};
console.log('before calling f: o.message="${o.message}"');
f(o);
console.log('after calling f: o.message="${o.message}"');

上面的代码会输出如下结果:

before calling f: o.message="initial value"
after calling f: o.message="set in f (previous value: 'initial value')"

这个例子中,可以看到在f函数内部修改了o,这些改动也会影响函数外的o对象。这里强调了基本类型和对象之间的主要区别。基本类型不能被修改(可以改变基本类型所赋值的变量,但是基本类型本身的值不会改变)。从另一方面来说,对象是可以被修改的。

需要清楚的是,函数内的o和函数外的o是完全不同的,但是它们都引用了同一个对象。可以通过下面的代码看出它们的不同之处:

function f(o) {
    o.message = "set in f";
    o= { 
        message: "new object!"
    };
    console.log('inside f: o.message="${o.message}"(after assignment)');
}
let o = {
    message: 'initial value'
};
console.log('before calling f: o.message="${o.message}"');
f(o);
console.log('after calling f: o.message="${o.message}"');

如果执行这个例子,会得到如下结果:

before calling f: o.message="initial value"
inside f: o.message="new object!" (after assignment)
after calling f: o.message="set in f"

理解这段代码的关键在于明白参数o(函数内部)和变量o(函数外)是不同的。当f函数被执行时,它们两个都指向了同一个变量,不过当o在 f 函数内被赋值时,它指向了一个全新的、完全独立的对象。而函数外的o依旧指向原始对象。

可以把JavaScript中的基本类型想象成计算机科学中的值类型,因为它们在赋值的过程中都对原始值进行了复制。对象则称为引用类型,因为当它们在赋值时,被赋值的变量和原来的变量都引用了同一个对象(也就是说,它们拥有同一个对象的引用)。