• 关于函数


    一些基本概念

    1.函数就是将一批重复的代码封装,以供调用;其本质就是代码块。

    2.函数的name属性是一个字符串。

    3.复杂的函数命名需要遵循“驼峰命名法”。

    4.函数后面圆括号里面的是函数的参数,花括号里面的是函数代码块。

    5.函数的参数分为形参和实参,形参是指:函数在定义时,圆括号里面的内容叫做形参,函数在调用时,圆括号里面的内容叫做实参,实参可以是变量也可以是值。

    6.函数是变量的特例。(var声明一个变量,可以是7种数据类型;函数只能声明一个函数)

    函数的几种声明方式

    1.匿名函数

    var f;
    f=function(x,y){
        return x+y
    }
    f.name //'f'

    **把一个函数给一个变量,这个函数就是一个匿名函数,这个变量就相当于一个函数,可以直接进行调用。

    2.具名函数(命名函数)

    function 函数名(参数){代码块}

    function f (x,y){
        return x+y
    }
    f.name //'f'

    3.具名函数赋值

    var x =function y (a,b){}
    console.log(y) //报错
    x.name //'y'
    
    function y (a,b){}
    console.log (y) //不报错
    
    //以上情况是由于JS的不一致

    4.window.Function

    var f = new Function('x','y','return x+y')
    f.name //"anonymous"(匿名的)

    一个小例子

    n=1;
    var f = new Function('x','y','return x +'n'+y')
    //等价于
    var f = new Function('x','y','return x +1+y')
    f(1,2) //4

    5.箭头函数

    var f = (x,y) => {return x+y}
    
    var f = (x,y) => x+y //{}可以与return一起去掉
    
    var n = n => n*n //若对象只有一个参数,()可以去掉

    函数调用

    call

    function f(x,y){
      return x+y  
    }

    内存图解:

    **params、fbody标注为假设标注,实际不存在**

    代码理解:

    f.params=['x','y']
    f.fbody='return x+y'
    f.call=function(){
      eval (f.body)  
    }
    f.call()
    
    //eval是window的全局对象
    //eval(‘xxxx’)给一个字符串当代码执行
    
    eval ('1+1')  
    //2
    eval ('1+"1"')
    //"11"

    **函数就是对象,函数的调用过程就是eval调用体的过程**

    call调用与()调用,this与arguments

    f (1,2) //(1,2)就是arguments
    //等价于
    f.call(undefined,1,2) //undefined就是this,1,2就是arguments

    call的第一个参数可以用this得到,后面的参数可以用arguments得到

    var f = function(){
      console.log(this);
    }
    f.call()//window  普通模式下若this是undefined,浏览器会将this默认变为window
    
    function f(){
        console.log(this)
    }
    f.call(1)//Number 对象 1
    
    
    var f = function(){
        'use strict'
      console.log(this);
    }
    f.call()//undefined  严格模式下若this是undefined,则为undefined
    
    function f(){
        'use strict'
        console.log(this)
    }
    f.call(1)//1

    //arguments  伪数组  原型链中没有Array.prototype这一环,__proto__指向的是Object.prototype,不能使用.push等属性

    call stack  调用栈

    function a (){
      console.log('a1')
      b.call()
      console.log(a2)
      return 'a'        
    }
    function b (){
      console.log('b1')
      c.call()
      console.log(b2)
      return 'b'      
    }
    function c (){
      console.log(c')
      return 'c'      
    }
    a.call()
    console.log('end')

    栈溢出(内存溢出)

    stack overflow

    (还不知道这个要怎么解决,以后遇到再说吧.. -_- ..)

    关于递归

    function sum (n){
      if(n==1){
      return 1  
        }  else {
            return n+sum(n-1)  
         }
    }
    
    sum = 5;//5+sum(4)
    //sum (4) //4+sum(3)
    //sum(3)//3+sum(2)
    //sum(2)//2+sum(1)
    //sum(1)

    关于作用域(scope)

    一些概念:

    Javascript 有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。

    例:

    var a = 1
    function f1 () {
      var a = 2
      f2.call()
      console.log(a)//2
      function f2(){
          var a=3
          console.log(a)//3
        }        
    } 
    f1.call()
    console.log(a)//1

    声明提前

    var a 
    function f1 () {
        var a
        a = 2
        function f2(){
            var a
            a = 3
            console.log(a)//3
        }     
       f2.call()
        console.log(a)//2
    } 
    a = 1
    
    f1.call()
    console.log(a) //1

     例:

    var a = 1
    function f1 (){
        f2.call()
        console.log(a)
        var a=2
        function f2(){
            var a=3
            console.log(a)
        }
    }
    f1.call()

    变量提升

    var a 
    function f1 (){
        var a
        function f2(){
            var a
            a=3
            console.log(a) //3
        }
        f2.call()
        console.log(a) //undefined
        a=2
    }
    a = 1
    f1.call()

    例;

    var a = 1
    function f1(){
        console.log(a)//undefined
        var a=2
        f2.call()
    }
    function(){
        console.log(a)//1 作用域里面没有a,则找父作用域里面的a
    }

    关于闭包

    若一个函数,使用了它作用域外的变量,那么(这个函数+这个变量)叫做闭包。

    其作用就是让这个变量值一直保存在内存中,要使用的时候即刻可以使用,另外可以通过闭包在函数外访问函数内部。

    var a=1
    function f (){
      console.log(a)  
    }

    关于立即调用函数

    声明一个函数,立即调用

    使用原因:

    1.全局变量不好用

    2.使用局部变量,需要一个函数,在函数里声明,立即调用

    3.匿名函数直接调用,会有报错

    解决办法

    (1)整体添加()

    (2)将函数()起来再.call()调用

    (3)直接再function前面加减号-或者加号+

    (4)在function前面加!或~ 》》推荐《《

    (5)使用代码块

     

    ES6:let的作用域就是{}里面,let不会变量提升

    待补充... ...

  • 相关阅读:
    面试题汇总--1
    行内元素与块级元素
    前端面试题整理---JS基础
    springmvc处理一个请求的全流程
    反射+动态代理+类加载+JVM
    json注解及序列化
    加密
    Thread setUncaughtExceptionHandler
    RunTime.getRunTime().addShutdownHook 添加钩子
    MySQL日志
  • 原文地址:https://www.cnblogs.com/BUBU-Sourire/p/11133142.html
Copyright © 2020-2023  润新知