美文网首页深究JavaScript
JavaScript函数(类比php)

JavaScript函数(类比php)

作者: 王中阳 | 来源:发表于2016-08-17 21:00 被阅读73次

    默认参数

    1. 和php中一样,还没有一种语法允许一个函数参数带有默认值。(咱们可以这么玩)
    function sum(a,b){
        b = typeof b === "undifine" ? 2 : b;
        return a + b;
    }
    
    sum(3,0); //3
    sum(3); //5
    

    任意多个参数

    1. js对函数的参数要求不严格,不一定非要传递指定个数的参数
    2. 多余的参数会被忽略掉,看下面的例子
    sum();//NaN
    sum(1,2);//3
    sum(1,2,100,300);//3
    
    1. 在php中,用func_get_args(),它返回传递给函数的参数的一个数组。
    2. arguments(技术拔高)
    function sum(){
        for(var i = 0,result = 0;i < arguments.length; i++){
            result += arguments[i];
        }
        return result;
    }
    
    sum();//0
    sum(1);//1
    sum(1,2);//3
    sum(1,2,3);//6
    sum(1,2,3,4);//10
    sum(1,2,3,4,5);//15
    
    • argumetns尽管看上去像数组,但实际上是一个对象,没有诸如push(),pop()这样的数组方法。
    function sum(){
        var args = Array.prototype.slice.call(arguments);
        var a = typeof arguments.push;
        var b = typeof args.push;
        console.log(a); //undefine
        console.log(b); //function
    }
    
    sum();
    
    - slice() 方法可从已有的数组中返回选定的元素
    - prototype 属性使您有能力向对象添加属性和方法。
    

    arguments.length的技巧

    1. 聪明的方法实现带默认值的函数
    function sum(a,b,c,d){
        switch(arguments.length){
            //注意:都不加break
            case 0: a=1;
            case 1: b=2;        
            case 2: c=3;        
            case 3: d=4;        
        }
        return a+b+c+d;
    }
    
    sum();//10
    sum(1);//10
    sum(11);//20
    sum(11,22);//40
    

    返回值

    1. js的函数总是会返回一个值。如果一个函数不使用return语句,那么会隐式的返回值undefine

    函数是对象(重点)

    • JavaScript中的函数是对象,理解这一点非常重要。它们带有自己的属性和方法
    function sum(a,b){ 
        return a + b;
    }
    
    sum.length; //2 -->该函数的参数个数
    
    • 函数对象的call()和apply()方法,提供了调用该函数的一种替代方法
    sum.call(null,2,3);//5
    sum.apply(null,[2,3]);//5 apply()接收的参数以数组的方式传递
    
    • 类似于我们php中的方法
    call_user_func('sum',2,3);
    call_user_func_array('sum',array(2,3));
    

    php语法详解

    不同的语法

    • 函数表达式:
    var sum = function(a,b){
        return a+b;
    };
    
    sum(1,2); //3
    
    • 这种语法展示了所谓的函数表达式(function expression),这和我们所熟悉的另一种叫做函数声明(function declaration)语法不同。
    • 根据上下文环境的不同,function关键字具有不同的语句含义。在函数表达式中,它是一个操作符。在函数声明中,它是一条语句。
    • 注意:函数表达式末尾必须加分号。函数声明则不是必须的。

    • 函数声明
    function sum(a,b){
        return a+b;
    }
    
    sum(1,2); //3
    

    • 命名函数表达式(named function expression)
    var sum = function sum(a,b){
        return a+b;
    }
    
    sum.name; //sum
    
    var sum = function(a,b){
        return a+b;
    }
    
    sum.name; //""
    
    • 主要用于调试

    作用域

    1. javascript中没有块作用域,只有函数作用域。
    2. 在一个函数中定义的任何变量,对于函数来说都是局部的,而且无法在函数之外看到它。
    3. 全局变量是那些在任何函数之外定义的变量。
    if(true){
        var true_global = 1;
    }
    
    if(false){
        var false_global = 1;
    }
    
    function sum(){
        var local = 1;
        is_local = 1;
        return true_global+local+is_local;
    }
    
    console.log(true_global);//1
    console.log(false_global);//undefined
    console.log(local); //ReferenceError: local is not defined
    console.log(is_local); //ReferenceError: is_local is not defined
    
    sum();
    
    console.log(true_global);//1
    console.log(false_global);//undefined
    console.log(local); //ReferenceError: local is not defined
    console.log(is_local);//1 is_local漏掉了var,全局命名空间被污染
    

    总结

    • true_global总是可用的
    • 即使是在一段不会执行的代码块中,false_global也总是声明了的,尽管没有初始化。使用它将会返回undefined(所有变量的默认值),这并不是错误。
    • 在函数sum()之外,local是不可用的,他是该函数的局部变量。试图在其局部作用域之外使用它,会产生错误。
    • 在使用sum()函数之前,is_local还没有声明,这将会导致错误;调用sum()会给is_local分配一个值。因为漏掉了var语句,会将这个值放到全局作用域中。开发中要避免这样做:防止全局命名空间被污染。

    提升

    • 当程序进入到一个新的作用域(例如,在一个新函数,全局作用域或eval()中),在函数中任何地方所定义的所有变量都移动或提升(hoisted)到作用域的顶层。
    var a = 1;
    function hoistingTest(){
        console.log(a);
        var a = 2;
        console.log(a);
    }
    
    hoistingTest(); //先显示"undefine" 再显示2
    
    • 解释一下原因:局部变量var a = 2;的声明提升到了顶层,重点是只有声明被提升,但是赋值没有被提升到作用域的顶层。真相是这样的:
    function hoistingTest(){
        var a;
        console.log(a);
        a = 2;
        console.log(a);
    }
    
    • 如何规避这种问题:
    1. 在顶部声明所有变量(可以看做类似定义一个php类并且所有属性都放到类的顶部,而不是散乱到方法里)
    2. 在需要的变量的时候才去定义它

    提升函数

    • 函数只是分配给一个变量的对象,所以,函数也可以得到提升。但是,因为函数定义方法的不同,提升方式会有所区别。
    //全局作用域
    function declare(){} 
    var express = function(){};
    
    (function(){
        //局部作用域
        console.log(typeof declare);//function
        console.log(typeof express);//undefine
        
        function declare(){}
        var express = function(){};
        
        console.log(typeof declare);//function
        console.log(typeof express);//function
    }());
    
    • 原理非常的简单,和变量的提升是一个道理:函数表达式express()只有var得到了提升。
    (function(){
        var express = undefined;
    
        //局部作用域
        console.log(typeof declare);//function
        console.log(typeof express);//undefined
        
        function declare(){}
        express = function(){};
        
        console.log(typeof declare);//function
        console.log(typeof express);//function
    }());
    
    

    一个敲代码,爱分享的人,我在这里!

    来玩啊

    相关文章

      网友评论

        本文标题:JavaScript函数(类比php)

        本文链接:https://www.haomeiwen.com/subject/sgamsttx.html