Javascript 进阶 5-3 参数

这个章节要来介绍参数

前几篇的文章对参数有一些介绍,这篇文章会对参数的各种状态进行更详细的介绍。

在介绍参数之前,一个函式在运行之前,会带入那些参数。

var globalVariables = '全域变数';var obj = {    afunction: function (para) {        var localVariables = '区域变数';        console.log(para, localVariables, arguments, this, globalVariables);    }};// 执行obj.afunction('一段描述', 2, 3);

我们可以看到,这段程式码在执行的时候带入的参数是3个,但接受的 function 只有 para 一个参数,也就是说,para 这个参数只会对应到 一段描述 这个字串,其他的2、3没有传进去。

看一下执行的结果~

http://img2.58codes.com/2024/201217700abXrd6oas.png

我们可以看到 globalVariables 以及 localVariables都有对应到正确的值,而全域变数之前的章节也有讨论过,如果找不到就会向外寻找直到找到为止,不然就回传 not defined。

this的部分后面会再详细的讨论,这里就先跳过。

重点是又多了一个 arguments 的变数,而且他好像是一个阵列,装着'一段描述', 2, 3 的三个值。

但其实这个 arguments 被称作 类阵列 ,但其实他不是阵列。虽然它可以被 for 迴圈处理内部的资料,但对于大部分阵列操作的指令他都无法执行。

Hoisting 影响参数的运行

function callName (a) {    console.log(a); // 小明}callName('小明');

上述执行的结果应该很明显就是小明没有甚么好讲的对吧~

那么如果改成下面这样呢?

function callName (a) {    console.log(a); // 小明        var a;    console.log(a); // 小明}callName('小明');

其实执行起来也还是小明喔!

原因是因为,我们再宣告一个变数的时候,这个变数名称已经存在的时候,这个宣告就是无效的。
所以 var a; 是无效的,自然 a 就还是保持在小明的状态。

那接下来我们把 a 改成 杰伦 呢?

function callName (a) {    console.log(a); // 小明        var a;    console.log(a); // 小明        a = '杰伦';    console.log(a); // 杰伦}callName('小明');

这时候就会是杰伦了,所以要改变内部的参数,直接覆盖就可以了!

那么重头戏来了喔~!

如果我今天在里面定义的是 函式陈述式呢?

根据之前学过的观念是,函式陈述式会最早被写入在记忆体空间中。

我们来实际操作看看

function callName (a) {    console.log(a);            function a () {}           var a;    console.log(a);         a = '杰伦';    console.log(a); }callName('小明');

http://img2.58codes.com/2024/20121770vhUOEBewuB.png

很明显在 a 还没被杰伦覆盖之前,传入的小明就被 函式陈述式 给附盖了。

所以虽然 函式陈述式 会最早被写入在记忆体空间中,但最早是指在这个函式内的 {} 的最早。

因此 函式陈述式 并不会比 '小明' 这个参数还早,所以显示的结果才是 函式陈述式。

定义的参数名称的规则

我们再定义函式接收的参数名称的时候,注意的只有参数的数量,参数的名称都是可以自定义的,只要不要重複就好。

我们接下来来看看下面的例子:

function callMore (d,c,b,a){    console.log(d,c,b,a);}var a = 'a';var b = 'b';var c = 'c';callMore(a, b ,c);

目前虽然传了3个参数进去,但函式接受的参数定义是4个,因此最后一个 a 就会在函式内被定义为 undefined。

传入参数是物件类型的资料,依然会维持传参考的特性

看一下範例吧~!

function callObject (obj) {    obj.name = '杰伦家';}var family = {    name: '小明家'}callObject(family);console.log(family);

所以这边执行后的结果很明显就是 family.name 会被改成 杰伦家。

http://img2.58codes.com/2024/20121770mPqzUA5YoK.png

这边也要提醒一下,尽量避免传入物件类型的资料后,又在函是内部修改资料内容,避免不预期的结果。

当然也是有人利用这种特性进行撰写,但其实这样的撰写风格不易追蹤,维护成本也较高。

因此不太建议这么写。

CallBack Function

function FnB (fn) {    fn('小明');}FnB(function (a) {    console.log(a);});

这样的函式直接执行,我们就先把参数预定在 FnB 中,等到执行的时候,传入ㄧ个 function,而 function 就会接收到 FnB 中的参数,并做ㄧ些处理。

我们也可以改写成

function callSomeone (name) {    console.log(name + '你好');}function FnB (fn) {    fn('小明');}FnB(callSomeone);

这样的写法,我们把 callSomeone 赋予到 FnB 的参数 fn上。

我们是透过函式表达式的方式传入到 FnB 的 function 中,因此真正执行的地方是在 callSomeone 的 function 里面。

而这样呼叫的方法呢,我们又称作 callback function。

类阵列 Arguments

刚刚有说到 arguments 是一个类阵列,每个函是在运行的时候都会有,他不需要特别宣告就可以取用。

他会接受所有传进来的值,并以一个类似阵列的结构乘装着,但他不是真正的阵列。

function callArg (a) {    console.log(a, arguments);}callArg(1,2,3,'a','5');

http://img2.58codes.com/2024/201217705GApMtxkrx.png

我们可以对这个 arguments 做 for 迴圈的取值动作

function callArg (a) {    console.log(a, arguments);        for (var i = 0; i < arguments.length; i ++) {        console.log(arguments[i]);    }}callArg(1,2,3,'a','5');

http://img2.58codes.com/2024/20121770noililLqnR.png

但我们就没办法对她使用 forEach 的方法

function callArg (a) {    console.log(a, arguments);        arguments.forEach(function () {});}callArg(1,2,3,'a','5');

http://img2.58codes.com/2024/20121770jVJvjMCYsO.png

关于甚么是类阵列,在这个章节还不需要先学习。

只要知道 arguments 是在函是运行的时候自带的变数,并且会乘装ㄧ切传入的值,这样就可以噜~

没有问题的话我们就可以往下一篇文章迈进了! 希望对各位有帮助~汪汪!


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章