[Day31] 参数

Day28 - 函式 中有提到,可以在函式的小括号内放入参数 (parameters),若有多个参数则以 逗号 , 做区格,而参数名称可以自行定义,与传入的值无关,如以下范例:

在呼叫函式的小括号内放入值,参数会依序接收

function fun(parameter1, parameter2) {
    console.log(parameter1, parameter2);
}
fun('参数1', '参数2');
// 参数1 参数2

预设参数 (Default parameters)

若传入的参数的值数量不足,则系统会先给予参数一个 undefined 的值

function fun(parameter1, parameter2, parameter3) {
    console.log(parameter1, parameter2, parameter3);
}
fun('参数1', '参数2');
// 参数1 参数2 undefined

参数预设值

若要避免没有传入值,可使用 ES6 的语法,使函式参数有其预设值

function fun(parameter1, parameter2, parameter3 = '我是参数预设值') {
    console.log(parameter1, parameter2, parameter3);
}
fun('参数1', '参数2');
// 参数1 参数2 我是参数预设值

参数与传参考

若带入参数的值是物件,他们会指向同一个物件参考路径,所以就算物件变成参数,依然会维持物件传参考的特性

function fun(obj) {
    obj.name = 'Mary';
}
var family = {
    name: 'Carol',
};
fun(family);

console.log(family); // {name: 'Mary'}

变数 family 赋予一个物件,并作为参数的值传入,参数 obj变数 family 会指向同一个物件参考路径,所以当 参数 obj 改变其物件内容,变数 family 也会受到影响

参数与提升(hoisting)

Day28 - 函式 有提到,函式陈述式在创造阶段时,会先在记忆体中将函式陈述式的所有内容做保留

以下在函式陈述式内放入函式陈述式,并将它与参数的名称命名为一样,可以发现 参数 nickName函式 nickName 取代,因此在函式内的函式陈述式一样会被提升,且不会比传进的 参数 nickName 更前方,因若为更前方,则答案会是 Carol Carol Mary

function fun(nickName) {
    console.log(nickName);
    
    function nickName() {}
    console.log(nickName);
    
    nickName = 'Mary';
    console.log(nickName);
}
fun('Carol');

// ƒ nickName() {}
// ƒ nickName() {}
// Mary

由此可知,上面例子运作流程如下:

// 1. 创造阶段
function fun(nickName) {
    console.log(nickName);
    
    function nickName() {}
    console.log(nickName);
    
    nickName = 'Mary';
    console.log(nickName);
}

// 2. 执行阶段
fun('Carol');

callback function

参数可以是原始型别,也可以是物件型别,当带入函式做为参数的值,使此函式成为另一个函式的参数且在另一个函式内调用此函式,称之为 callback function

function fun(fn) {
    fn('Carol');
}
fun(function(nickName) {
    console.log(nickName);
});

也可以将呼叫 fun 函式 小括号内的函式另外提出来,如下所示:

function fun1(nickName) {
    console.log(nickName);
}
function fun2(fn) {
    fn('Carol');
}
fun2(fun1);

函式引数 (arguments)

上面有提到函式的参数只会提取相对应的数量,而函式引数 (arguments) 则会取得所有传入的值,并使之成为一个类阵列,而类阵列虽然很像阵列,但无法使用绝大多数的阵列方法

在以下例子中,只用 1 个 参数 a 来接收传入的值,其余传入的值,可利用 arguments 来显示 (arguments 是专有名称,不用另外定义)

function fun(a) {
    console.log(a, arguments);
}
fun(1, 2, 3, 4);
// Arguments(4) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]

其余参数 (rest parameter)

其余参数 (rest parameter) 是 ES6 的语法,它可以取得不定数量的参数,作用类似於 函式引数 (arguments),但其余参数是阵列,arguments 是类阵列

function fun(a, ...others) {
    console.log(a, others);
}
fun(1, 2, 3, 4);
// 1 (3) [2, 3, 4]

需要注意的是其余参数必须为最後一个参数,且在此参数中只能有一个是其余参数,否则会出错

function fun(...others, a) {
    console.log(a, others);
}
fun(1, 2, 3, 4);
// 错误讯息 - Uncaught SyntaxError: Rest parameter must be last formal parameter

function fun(a, ...others1, b, ...others2) {
    console.log(a, others1, others2);
}
fun(1, 2, 3, 4, 5, 6);
// 错误讯息 - Uncaught SyntaxError: Rest parameter must be last formal parameter

额外补充 - 变数的重复宣告

当宣告一个变数,而此变数已经存在,这个宣告就无任何作用,并不会再变成系统预设值 undefined

var nickName = 'Carol';

var nickName;

console.log(nickName); // Carol

所以,在参数传递时,若参数已经定义好值,就算再重复做宣告,不会影响到此参数的值

function fun(nickName) {
    console.log(nickName);
    
    var nickName;
    console.log(nickName);
    
    nickName = 'Mary';
    console.log(nickName);
}
fun('Carol');

// Carol
// Carol
// Mary

参考文献

六角学院 - JavaScript 核心篇

MDN - 预设参数

MDN - 其余参数


<<:  Day 31: 【全系列终】架构考古学

>>:  JS 32 - 资料丢进来,就能计算所需样本数量!

JavaScript入门 Day29_抓html物件

今天要讲的是在JavaScript里怎麽抓到html的东西,那抓到之後就可以对那物件做一些事 那其实...

[Day31]那转职稽核好玩吗

「那转职成稽核好玩吗?」 「超~好~玩~~~~~」 「但~」 「也~好~精~实~噢~」 进步 我觉得...

离职倒数9天:铺好轨道的人生

这几天都在屋久岛爬山。这里没网路才是常态,打开有网路简直像是惊喜。 每天都要找地方发铁人文,也是满特...

Log Agent - Fluent Bit Service配置与内建 API

Fluent bit回顾 Log Agent - Fluent Bit 简介 Log Agent -...

每日挑战,从Javascript面试题目了解一些你可能忽略的概念 - Day9

tags: ItIron2021 Javascript 前言 昨天我们简单讨论了恼人的强制转型问题,...