zoukankan      html  css  js  c++  java
  • javascript中函数的全解简介

    <script  language="javascript">
    //切记特殊的两种函数声明方式
    /*
    //Function 构造
    var f=new Function("x","document.write(x);");
     f(2);

     //函数直接量
     var g=function(y)
     {
     alert("I am the Function g().");
     }
     g();  
    */
    function Rectangle_area(){return this.width*this.height;}
    function Rectangle_perimeter(){return 2*(this.width+this.height);}
    function Rectangle_set_size(w,h){this.width=w;this.heigh=h;}
    function Rectangle_enlarge(){this.width*=2;this.height*=2;}
    function Rectangle_shrink(){this.width/=2;this.height/=2;}
    //初学javascript中的面向对象的编程方式
    //构造Retangle对象定义一个构造函数方法
    //构造函数不仅要初始化属性,还给方法赋值
    function Rectangle(w,h)
    {
     //初始化对象的属性
     this.width=w;
     this.height=h;
     //定义对象的方法
     this.area=Rectangle_area;
     this.perimeter=Rectangle_perimeter;
     this.set_size=Rectangle_set_size;
     this.enlarge=Rectangle_enlarge;
     this.shrink=Rectangle_shrink;
    }
    var r=new Rectangle(3,4);
    var a=r.area();
    r.enlarge();
    var p=r.perimeter();
    document.write("The rectangle's width is :"+r.width+"<br />This rectangle'height is :"+r.height);
    //alert("The rectangle's area is :"+a+",The rectangle'perimeter is :"+p);


    /*
    自定义异常错误!
    throw new Error("there is something wrong!");

    */

    /*
    直接函数的更多应用
    直接函数和Function构造函数一样,函数直接两创建的是未命名函数,而且不会自动地将这个函数存储在
    属性中。但是,比起Function函数构造创建的函数主体必须用一个字符串说明,用这种方式来表达一个长
    而复杂的函数是很笨拙的。但是函数直接量的主体使用的却是标准的javascript语法。而且函数直接量植被
    解析和编译一次,而作为字符串传递给Function构造函数的javascript代码则在每次调用构造函数时只需
    被解析和编译一次。
    */

    //作为数据的函数实例
    function add(x,y){return  x+y;}
    function subtract(x,y){return x-y;}
    function multiply(x,y){return x*y;}
    function divide(x,y){return x/y;}
    //以下的函数可以将上面的某个函数作为参数
    //他的两个参数是两个运算数。
    function operate(operator,operand1,operand2)
    {
     return operator(operand1,operand2);
    }
    //我们可以调用该函数
    var i=operate(add,2,3);
    document.write("<br />operate(add,2,3)的结果是:"+i);

    //看到这里我不禁想到了c#中的委托代理
    //这里就给了我们一个生动形象的实例来帮助我们理解委托代理
    //C#中的委托代理的目的不就是为了将函数作为参数来传递
    //在javascript中作为数据的函数,说白了就是为了实现我们在c#中的委托代理的目标.

    var operators=new Object();
    operators["add"]=function(x,y){return x+y;}
    operators["subtract"]=function(x,y){return x-y;}
    operators["multiply"]=function(x,y){return x*y;}
    operators["devide"]=function(x,y){return x/y;}
    operators["pow"]=Math.pow;

    //以下的函数将运算符名作为参数,在数组中检索这个运算符.
    //然后对运算数调用检索到的函数
    //注意调用这个运算符函数的语法
    function operate2(op_name,operand1,operand2)
    {
     if (op_name==null)
     {
      return "unknown operator!";
     }
     else
     {
      return operators[op_name](operand1,operand2);
     }
    }

    //我们就可以使用以下的方式调用该函数计算值 ("hello"+" "+"world!")
    //var j=opertate2("add","Hello",operate2("add"," ","world!"));
    var k=operate2("add","Hello",operate2("add"," ","world!"));
    document.write("<br >opertate2('add','Hello',operate2('add','','world!'))的结果是:"+k);
    document.write("<br>operate2('pow'.10,2)的结果是:"+operate2("pow",10,2));
    //个人意见
    //这种使用方法实际上就是在javascript中提到的属性的关联数组的用法,为我们的编程提供了
    //强大的灵活性.

    //javascript函数的主体是在局部作用域中执行的,该作用域不同于全局作用域.这个新的作用域
    //是通过调用对象添加到函数作用域链的头部创建的.因为调用对象是作用域链的一部分,所以
    //在函数体内可以把这个调用对象的德属性作为变量来访问.用var语句声明的局部变量创建后
    //作为调用对象的属性,而且函数的形式参数也可用于调用对象的属性.

    /*
    函数调用的实际参数:Arguments对象.
    */
    function f(x,y,z)
    {
     //首先检查传递参数的数量是否正确.
     if (arguments.length!=3)
     {
      throw new Error("Function f called with "+arguments.length+"arguments ,but it expects 3 arguments!");
     }
    }
    //f(1,2,6,6);

    function max()
    {
     var m=Number.NEGATIVE_INFINITY;
     //遍历所有参数,检索并保存其中最大的参数
     for (var i=0;i<arguments.length ;i++ )
     {
      if(arguments[i]>m) m=arguments[i];
      document.write("<br />arguments["+i+"]="+arguments[i]);
     }
     return m;
    }

    var largest=max(1,6,9,100,99,5);
    document.write("<br />max(1,6,9,100,99,5)的结果是:"+largest);
    /*
    以上的实例中的Arguments对象很容易让我们认为它是一个数组,
    但我要说明的一点就是这里的arguments不是一个数组而是一个对象,虽然它也有length属性
    但我们如果把它看作偶然具有了一些带编码的属性的对象更合适些.
    */

    //aruments对象还有callee属性
    //用来引用当前正在执行的函数.看下面这个求阶乘的函数
    var t=function(x)
    {
     if(x<=1) return 1;
     return x*arguments.callee(x-1);
    }
    document.write("<br />5的阶乘是:"+t(5));


    //函数的属性和方法
    //知道了arguments数组的length属性指定了楚地为该函数的实际参数数目.但是函数自身的length属性的含义
    //却非如此,它是只读的.返回的是函数需要的实际参数数目,也就是在函数的形式参数列表中声明的形式参数
    //的数目.
    function check(args)
    {
     var actual=args.length;
     var expected=args.callee.length;
     if (actual!=expected)
     {
      throw new Error("Wrong number of arguments:expected : "+expected +";actually passed  "+actual);
     }
    }

    function f2(x,y,z)
    {
     check(arguments);
     return f2.counter++;
    }
    //f2(4);
    //同时函数还可以定义自己的属性
    f2.counter=0
    document.write("<br />第一次引用f2时的counter属性:"+f2(1,1,1)); //此时counter=2
    document.write("<br />第二次引用f2时的counter属性:"+f2(1,1,1)); //此时counter=3
    //document.write("<br />第三次引用f2时的counter属性:"+f2.counter);  //此时counter=3
    //函数的apply()和call()方法
    //call 和apply方法的第一个参数都是要调用的函数对象,在函数体内这一参数可以使用this的值,
    //call()的剩余参数是传递给要调用的函数的值.
    //apply()区别于call()的地方就是apply()的参数是用数组来传递的
    var  d=new Array(1,2,3);
    f2.call(f,1,2,3);                        //此时counter=4
    document.write("<br />第三次引用f2时的counter属性:"+--f2.counter); 
    f2.apply(this,d);                       //此时counter=2
    document.write("<br />第四次引用f2时的counter属性:"+f2.counter);
    f.call(f2,1,2,3);                        //此时counter=2,这里没有调用f2
    document.write("<br />第五次引用f2时的counter属性:"+f2.counter);
    //以上现象比较怪异,应该多想想!
    //实际上以上主要在让我熟悉++的运算
    </script> 

  • 相关阅读:
    dljd_008_jdbc中调用Statement的execute()执行DQL,DDL,DML
    dljd_007_jdbc编程中的statement执行DML/DDL
    【数据结构】可持久化线段树
    【数据结构】可持久化并查集
    【图论】TarjanLCA算法
    【图论】KruskalMST算法
    【基础】标准模板
    【数学】位运算
    【数据结构】Trie
    【数据结构】线段树(名次树)
  • 原文地址:https://www.cnblogs.com/itelite/p/1036119.html
Copyright © 2011-2022 走看看