JavaScript中的函数

本文是前端学习笔记中的第二篇,对应的是渡一教育的web前端开发JavaScript精英课js中的第七课时

JS中的函数给我的感觉还是蛮新奇的,以前只学过C和Java,都是不可以函数嵌套的强类型语言,(尽管JDK10以后,Java引入了局部类型推断(Local-Variable Type Inference),即我们平时说的var),弱类型语言的一些特性,我还是需要些时间慢慢去适应

 

目录

一.  弱类型语言无法输出地址

二. 3种函数体定义方式

      函数声明

      函数表达式

         (1)函数声明

         (2.1)命名函数表达式

         (2.2)匿名函数表达式

三.  形参和实参列表


 

一.  弱类型语言无法输出地址

弱类型语言的方法虽然可以输出,但是得到的并不是期望的地址值,而是整个函数体,尽管JS也有堆和栈的概念,但是地址不会被输出

<script>
    function testMethod() {
        alert("我真帅");  
    }

    testMethod();
    console.log(testMethod);      // 控制台中输出 内容同下
    document.write(testMethod);   // function testMethod() { alert("我真帅"); }
</script>

  输出到浏览器屏幕上的是 function testMethod() { alert("我真帅"); },而在控制台中输出则更规范,保留了代码格式,一般都在控制台中输出

二. 3种函数定义方式

    3种定义方式,可以总的被归纳为两种,如下所示

  • 函数声明

  • 函数表达式

    其中,函数表达式还可以再进一步细分为命名函数表达式匿名函数表达式

 

(1)函数声明

<script>
   function test() {
        console.log("函数声明");
   }
   // test();
</script>

  如上所示,一个函数便被声明了,但是不会执行,因为此时没有JS代码调用它,此时只需要把注释放开,便可在控制台看到输出

 

 (2.1)命名函数表达式

<script>
   var named = function abc () {
        console.log("命名函数表达式");
   }
   named();
</script>
 命名函数表达式的命名二字,表现在function后面的“abc”那,但是实际上若想调用这个函数还是需要named();这样调用,后面的“abc”基本上是没有任何意义的,。因此实际开发一般都是使用匿名函数表达式

(2.2)匿名函数表达式

<script>
     var unnamed = function () {
         console.log("匿名函数表达式");
     }
     unnamed();
</script>

  匿名函数表达式结构更加清晰,删除了无用的命名

 

  那么,尽管命名函数表达式没用,那么它们的区别在哪里呢?

  答案其实就是命名那

  

<script>
        // (1)函数声明
        function test() {
            console.log("函数声明");
        }
        // (2)函数表达式
        // (2).1 命名函数表达式
        var named = function abc () {
            console.log("命名函数表达式");
        }
        // (2).2 匿名函数表达式
        var unnamed = function () {
            console.log("匿名函数表达式");
        }
        // (2).1和(2).2的区别在于各自的name属性 2.1为abc 2.2为unnamed 此外,以函数声明方式定义函数同样有name 即它本身
        console.log("test.name = " + test.name);            // test
        console.log("named.name = " + named.name);          // abc  唯一一点不同之处 开发一般都用匿名
        console.log("unnamed.name = " + unnamed.name);      // unnamed
</Script>

  如上代码

  可以看到,无论是函数声明还是匿名函数表达式,方法的name属性值都是各自的方法名,唯独命名函数表达式是function后面跟着的变量名“abc”,区别仅在于此

 

三.  形参和实参列表

 JavaScript中的形参因为弱类型语言的缘故,不再需要定义变量数据类型,直接写名字即可,且不限制传递参数个数(类似于Java的JDK5引入的可变参数,不过功能更加强大),但这样的同时也会引发一些问题,比如传递的参数个数和定义的形参个数不同,此时需要以arguments对象取出实参。 具体看下面的代码

 

<script>
    function js (a,b) {
        // 形参相当于 var a,b;
        if (js.length > arguments.length) {
            console.log("形参多了");
        } else if (js.length < arguments.length) {
            console.log("实参多了");
        } else {
            console.log("相等");
        }
        for (var i = 0;i<arguments.length;i++){
            alert(arguments[i]);
        }

        js(1,2,3,undefined,null,NaN);
</script>

   形参定义了两个,但实际传递的参数有5个,此时如果想使用其余被传递的参数,则需要使用arguments对象获取,注意,arguments是对象而不是数组,arguments[0]只是其一个属性,而这个属性是传递的实参的副本

 

 除此之外,形参还和arguments对象的属性存在映射关系,若修改了形参值会通过映射改变arguments对象属性的值(但二者实际上并非指向同一块内存),即形参值,但是也存在一定的约束关系,形参值只能修改和实参值共有的部分,如下所示

  

<script>
    function testArgs(a,b,c,d) {
        // 相当于 var a,b,c,d;
        a = 11;
        b = 22;
        c = 33;
        d = 44;
        console.log("arguments[0] = " + arguments[0]); // 11
        console.log("arguments[1] = " + arguments[1]); // 22
        console.log("arguments[2] = " + arguments[2]); // 33
        console.log("arguments[3] = " + arguments[3]); // undefined
        //由此可见 这种映射关系只存在于实参和形参的共有部分
    }

    testArgs(1,2,3);

</script>

  实际被传递的参数只有3个,但此时形参定义了4个,那么arguments数组的属性也只有arguments[0],arguments[1],arguments[2],此时查看arguments[3]自然是undefined

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值