zoukankan      html  css  js  c++  java
  • 浅谈JavaScript函数

    JavaScript作为一种基于对象(非严格面向对象)的语言,函数在JS中的地位非同一般:用函数声明类和对象。甚至函数本身也是对象。

    一、函数的三种声明方式辨析。

    1.function命令

    function printAbc(){

    console.log('ABC');

    }

    2.函数表达式(变量赋值形式)

    var printAbc = function (){

    console.log('ABC');

    };

    注意:1、使用函数表达式形式时务必要有分号。

    2、此时function后函数名可有可无,且只在函数内部有效

    var fname = function abc(){

    console.log(abc.name);  /* xxx.name 方法非ECMAScript标准 */

    }

    fname();   //abc

    abc(); //ReferenceError: abc is not defined

    这种写法的用处有两个,一是可以在函数体内部调用自身,二是方便除错(除错工具显示函数调用栈时,将显示函数名,而不再显示这里是一个匿名函数)。

    3.使用Function构造函数

    JS中一切都是对象,声明函数也可以看作构造函数对象。

    var f = new Function("a","b","return a+b");

    f(1,2);   //3

    第1到第N-1个参数是函数参数,第N个参数是函数体。

    有些人认为,这种定义方式只有傻逼才会用,因为除了奇葩以外别无好处,但是其实真的是有用的- -。

    实现一个在线运行和编辑JS代码的程序:

    <html>
    <head>
    <title>JS Run Online</title>
    <script type="text/javascript">
    function btnOnclick(){
    var getDiv = document.getElementById("TextArea");
    var text = getDiv.value;
    var f = new Function(text);
    f();
    }
    </script>
    </head>
    <body>
    <div align="center">
    <textarea id="TextArea" cols="30" rows="10"></textarea>

    <input type="button" value="Run" onclick="btnOnclick()">
    </div>
    </body>
    </html>

    这段程序功能看起来简单,但是如果用静态语言将是很难实现的,Function构造函数正是JavaScript是动态语言的有力证明——可以在运行过程中让程序修改程序本身,而动态语言的核心就是:所有参数,包括函数体,都视作字符串。(个人理解,不妥望指正)。

    二、函数名的提升

    JS中,使用function命令声明函数是,该声明会被提到代码头部,如:

    f();

    function f() {};

    以上代码并不报错,因为function f() {};被提到了代码头部。

    但是,如果采用函数表达式,就是另外一种情况了:

    f();

    var f = function () {};

    // TypeError: undefined is not a function

    因为以上代码等同于:

    var f;

    f();

    f = function () {};

    当调用f的时候,f只是被声明,还没有被赋值,等于undefined,所以会报错。因此,如果同时采用function命令和赋值语句声明同一个函数,最后总是采用赋值语句的定义。

    var f = function (){

    console.log('1');

    };

    function f() {

    console.log('2');

    }

    f();//1

    因此,

    1、函数若重复声明,则视作只声明了一次,以最后一次声明为准。

    2、不能在条件语句中声明函数。

    现实情况下,由于浏览器的容错性,条件语句中使用function命令不会报错,但是由于函数名提升,条件语句本身就会无意义:

    if (0){

    function f() { console.log('1'); }

    }

    f();//1

    3、若确实需要用条件语句生成函数,只可采用函数表达式。

    if (xxx){

    var f = function (){xxx;};

    };

    三、函数的参数。

    1、length属性。

    函数定义时参数的个数。

    function f (a,b) {}

    console.log(f.length); //2

    2、参数的省略。

    函数从前向后取用参数,若多余,则后面忽略,若不足,则后面补undefined。若欲省略前面的参数,则应该主动显式传入undefined。

    function f(a,b){
        return a;
    }
    
    f(,1) // error
    f(undefined,1) // undefined

    3、默认值。

    可以通过以下方式设置参数默认值:

    function f(a){
        a = a || 1;
        return a;
    }
    
    f('') // 1
    f(0) // 1

    缺点是:a不能为0或空字符串,否则函数即使有参数也会使用默认值。

    4、函数参数的传递方式。

    JS的参数传递方式是值传递,这意味着函数体内修改参数值不会影响到外部:

    var a = 1;

    function f (a){

    a = 2;

    }

    f(a);

    console.log(a);    //1

    值得注意的是,对于符合类型的数据,属性值得传递是地址传递:

    var o = {a:1};

    function f(o){

    o.a = 2;

    }

    f(o);

    console.log(o.a);    //2

    var a = [6,7,8];

    function f(a){

    a[0] = 0;

    a[1] = 1;

    a[2] = 2;

    }

    f(a);

    console.log(a[0],a[1],a[2]); // 0 1 2

    利用这个特性,当我么需要对某个变量采用地址传递时,可以将它写成全局对象的一个属性:

    var a = 1;

    function f(a){

    window.a = 2;

    }

    f(a);

    console.log(a);   //2

    4、arguments对象

    //未完待续

  • 相关阅读:
    (Java随机数举例)随机扔一千次硬币的正反次数
    hibernate+spring的整合思路加实例(配图解)
    从零开始学C++之IO流类库(三):文件的读写、二进制文件的读写、文件随机读写
    ssh连接Linux自动断开后再也无法连上的问题
    面试题10:二进制中1的个数
    C 语言统计关键字出现次数
    在Eclipse中Attach Source
    Visual Sudio 2012转换界面风格
    java 判断字符串IP合法性以及获取IP的数值形式
    java.lang.string split 以点分割字符串无法正常拆分字符串
  • 原文地址:https://www.cnblogs.com/taoshen/p/4295706.html
Copyright © 2011-2022 走看看