zoukankan      html  css  js  c++  java
  • js函数知识

    1、函数基本知识

    通过函数可以封装任意条语句,在任何地方调用,js中用function关键字来声明,

            //基本格式,函数名,传递参数,代码块
            function functionName(arg0,arg1,arg2,……,argN){
                 statements
            }
            
            //实例
            function sayHi(name,message){
                  console.log("hello "+name+","+message)
            }
            sayHi("double","how are you")    //普通的函数名调用函数
    
            function sum(numb1,numb2){
                 return numb1+numb2;
                 console.log("find me ?")    //因为之前有return,所以不会再执行
            }
            var result=sum(1,2);             //声明变量的做法来调用函数
    
    
            function summ(numb1,numb2){
                  return;                    //return可以不带任何返回值,这时候会返回undefined
                  console.log("hello")
            }
    
            function diff(numb1,numb2){      //一个简单的比较函数
                 if(numb1<numb2){
                      return numb2-numb1;
                 }
                 else{
                      return numb1-numb2;
                 }
            }

    1.1理解参数

    js中的参数在其内部使用一个数组表示,所以无论参数的数据类型,个数都没关系,而且参数也不一定会用上的。

    函数体内可以通过arguments对象访问到参数的数组,从而获得每一个参数。arguments对象和数组相似,可以中括号表示,有length;

    参数名不是必须的,为了方便而已,也可以通过arguments[0]访问到

            function change(){
                console.log(arguments.length)
            }
            var zero=change()         //0      可以通过length来展现
            var one=change("one")     //1
            var two=change("two",2)   //2
            
            //没有参数名
            function doAdd(){
                if(arguments.length==1){
                    console.log(arguments[0]+10);
                }else if(arguments.length==2){
                    console.log(arguments[0]+arguments[1])
                }
            }
            doAdd(1)      //11
            doAdd(1,2)    //3
    
            //有参数名
            function anotherAdd(num1,num2){
                if(arguments.length==1){
                     console.log(num1+10);
                }else if(arguments.length==2){
                     console.log(num1+num2)
                }
            }
            anotherAdd(1)    //11
            anotherAdd(1,2)  //3
    
            function again(num1,num2){
                arguments[1]=10;
            //这里num2的值也就变成10,arguments的值与对应命名参数的值保持同步,内存空间还是独立的;没有传递值得命名参数为undefined          
                console.log(arguments[0]+num2)
            }

    1.2没有重载

    所谓的没有重载就是说,不可以为函数两个定义,因为js的参数是数组,没有签名,做不到真正的重载。两个相同的函数则以后一个为准。

    Function类型

    也是引用类型,每个函数就是Function类型的实例,都与其他引用类型具有相同的属性和方法。函数为对象,所以函数名只是指向函数对象的指针

    声明变量有两种方式。看例子吧。

          function sum(num1,num2){     //函数声明来定义函数
                return num1+num2
          }
    
          var sum=function(num1,num2){  //函数表达式定义函数
                return num1+num2
          }
    
          //函数名仅仅为指针;所以也能理解上面所说的函数没有重载
          function one(num1,num2){
               return num1+num2
          }
          var two=one
          var one=null
          console.log(two(1,2))    //3  即使one为null

    函数声明和函数表达式之间的相爱相杀

    解析器对他们两个态度可是不同的

    对于函数声明,解析器会优先读取,对其有个函数声明提升的过程(function declaration hoisting)

    对于函数表达式,解析器可就不会优先了,只有读取到其,才会被解释执行

          console.log(sum(1,2))        //3
          function sum(num1,num2){     
                return num1+num2
          }
    
          console.log(another(1,2))    //another is not a function
          var another=function(num1,num2){
                return num1+num2
          }

    当然还有构造函数法,不推荐使用,导致代码的二次解析,一次是常规js的,一次是构造函数的

    也就是函数可以作为值传参

         function sum(someFunction,value){        //基本的函数中的嵌套
                 return someFunction(value)
         }
    
         function multiplys(num){                 //内部的函数
                return num*num
         }
    
         console.log(sum(multiplys,2))            //调用函数,访问内部函数的指针,不需要()调用

    利用作为值得函数,可以按照某一属性对数组进行排序

         function compare(value){                 //想要通过比较obj的属性,这里的value只是参数,没有被实例化;而在简单的数组中都已经被实例化了
               return function(obj1,obj2){
                  var value1=obj1[value]
                  var value2=obj2[value]
                  return value1-value2
               }
         }
    
         var data=[{name:"double",age:24},{name:"zom",age:23},{name:"mike",age:32}]
         data.sort(compare("age"))
         console.log(data)         //23,,24,32来排序

    2、函数内部的属性

    在函数的内部,一般有两个对象

    this对象:this引用的是函数执行的环境对象,即this值(在全局环境中,this则代表的是window)

    arguments对象:类数组对象,保存函数参数;有个callee属性,此属性是个指针,指向拥有arguments对象的函数

    ES5规定了另个一个函数对象的属性caller,保存着调用当前函数的函数引用,在全局作用域中调用当前函数则为null

         //递归函数
         function sum(num){
              if(num<=1){
                  return 1
              }
              else{
                  return num*arguments.callee(num-1)     //消除紧紧耦合,保证完成递归函数,所以用callee属性
              }
         }
         var summ=sum;
         sum=null
         console.log(summ(10))
    
    
        //this
        window.color="red"
    
        function sayColor(){
             console.log(this.color)
        }
    
        sayColor()                    //red
    
        var another={color:"blue"}   
        another.putColor=sayColor     //函数名只是个指针
        another.putColor()            //blue
    
    
      //函数对象属性caller
      function outer(){
          inner()
      }
     /*  function inner(){
          console.log(inner.caller)
      }*/
      function inner(){
          console.log(arguments.callee.caller)    //减少耦合
      }
      outer()             //outer()函数

    3、函数的属性和方法

    每个函数有两个属性

    length属性:表示函数的参数名个数

    prototype属性:保存引用类型所有实例方法,不可枚举,用for-in无法实现

    每个函数都包含两个非继承的方法;都是在特定的作用域中调用函数,实际等于设置函数体内this对象的值

    apply()方法:接受两个参数,一为在其中运行函数的作用域,一为参数数组(Array的实例或者arguments对象)

    call()方法:接受的第一个参数是this值没变化,第二个不是数组了,直接传递给参数即可,看例子吧

       function sum(num1,num2){
           return num1+num2
       }
    
       function oneSum(num1,num2){
           return sum.apply(this,arguments)         //arguments对象
       }
       function twoSum(num1,num2){
           return sum.apply(this,[num1,num2])       //数组
       }
    
       console.log(oneSum(1,2))
       console.log(twoSum(1,2))
    
       function three(num1,num2){
           return sum.call(this,num1,num2)          //参数直接传递
       }
       console.log(three(1,2,3))   
      
      //apply()和call()方法可以扩充函数的作用域
      window.color="red"
      var one={color:"red"}
    
      function sayColor(){
          console.log(this.color)
      } 
      sayColor()                  //red
    
      sayColor.call(this)         //red
      sayColor.call(window)       //red
      sayColor.call(one)          //blue   这里的作用域为one中的了,不需要再将函数放到one中等操作

    ES5规定还规定一个方法bind(),创建一个函数实例,其this值被绑定到传给bind()函数的值,

      window.color="red"
      var one={color:"blue"}
    
      function sayColor(){
          console.log(this.color)
      }
    
      var another=sayColor.bind(one)     //ES5的函数方法,创造一个函数实例了,并且绑定的this值传递给函数了
      another()                          //blue
  • 相关阅读:
    nginx-1.8.1的安装
    ElasticSearch 在3节点集群的启动
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    sqoop导入导出对mysql再带数据库test能跑通用户自己建立的数据库则不行
    LeetCode 501. Find Mode in Binary Search Tree (找到二叉搜索树的众数)
    LeetCode 437. Path Sum III (路径之和之三)
    LeetCode 404. Sum of Left Leaves (左子叶之和)
    LeetCode 257. Binary Tree Paths (二叉树路径)
    LeetCode Questions List (LeetCode 问题列表)- Java Solutions
    LeetCode 561. Array Partition I (数组分隔之一)
  • 原文地址:https://www.cnblogs.com/iDouble/p/8372468.html
Copyright © 2011-2022 走看看