ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript笔记(函数)

2022-06-18 09:33:43  阅读:141  来源: 互联网

标签:function 函数 作用域 JavaScript 笔记 arguments var fn


函数

一、函数基础

1、函数的定义

将特定的代码片段,抽取成为独立运行的实例,就是函数;

函数好处:代码复用、方便维护、便于理解、使用简单;

2、函数的创建

  • 在当前函数所在script标签创建时,优先将该函数存储在堆中,并且函数名存储在栈中

  • 当前这个代码所在的script标签的上面的script的标签中任意函数和全局变量都是可以被调用的

  • 但是当前代码所在的script标签下面的script的标签中函数和全局变量是不可以调用的

  • 函数名:驼峰式命名法,首字母一般都是小写,如果该函数是构造函数,函数名首字母需要大写

  • 函数后面的()是执行当前函数需要传入参数内容

  • {}里面是函数的语句块,当执行函数时,该语句的内容就会被执行

命名函数

function fn(a,b){     //fn即为函数名
    console.log(a+b);   //调用函数时执行此语句块
}
fn(10,20);        //调用函数并传入参数

匿名函数

//代码运行到定义匿名函数后才可以调用该匿名函数
var fn=function(){
    console.log(arguments.callee);//arguments.callee 就是函数本身
}

自执行函数

(function(){
    //自己执行自己,也是匿名函数
})();

构造函数定义函数

var fn=new Function("a","b","console.log(a+b)");
fn(3,5);

二、作用域与作用域链

1、作用域

作用域就是变量作用的范围,分为全局作用域和局部作用域

作用域就是代码的执行环境,全局执行环境就是全局作用域,函数的执行环境就是私有作用域,它们都是栈内存。

某个执行环境中所有的代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出时,如关闭浏览器或网页,才会被销毁)

var a=10;
//函数外为全局作用域,函数外var定义的变量是全局变量
function fn(a){   //参数是局部变量
    //函数内为局部作用域   
    var a=20;  //函数里var定义为局部变量
    console.log(a);//20 优先局部变量,没有再去外面找全部变量
};
console.log(a);//10 无法调用函数内局部变量,打印全局变量10

2、作用域链

作用域链就是执行代码时,会首先在自身函数内找变量,找不到再去外部找,再找不到就去window环境找,这个过程就是作用域链

var a=10;
function fn(){
    function fn1(){
        console.log(a);//10 执行此代码输出a,首先在函数内fn1找变量,找不                到,然后去外部fn函数找,找不到去全部window找,这时找到a=10;                这个过程就是作用域链
    }
}

当代码在一个环境中执行时,会创建变量对象的一个作用域链(作用域形成的链条)

  • 作用域链的前端,始终都是当前执行的代码所在环境的变量对象

  • 作用域链中的下一个对象来自于外部环境,而在下一个变量对象则来自下一个外部环境,一直到全局执行环境

  • 全局执行环境的变量对象始终都是作用域链上的最后一个对象

内部环境可以通过作用域链访问所有外部环境,但外部环境不能访问内部环境的任何变量和函数。

三、参数、return

function fn(a,b){
            // a,b是参数,参数可以是任意内容,如果没有对应填入,该参数就是undefined
            // 执行函数时,填入的参数就相当于给参数赋值
            // js是一个弱类型语言,因此,参数不能强制约定类型
            // ES5中不能设置参数的默认值
            console.log(a+b);
        }
fn(3);执行函数时填入值与函数参数顺序是一一对应关系
function fn(obj){
              // 相当于给obj赋值一个o,obj和o的引用地址相同
              // 当修改obj的属性时,全局的o属性也会被修改
              obj.a=10; //此时o对象中的属性也变成10
          }
  
          var o={a:1};
          fn(o);

arguments参数集

  • 它只能出现在函数内

  • 它用来接受动态的实参

  • 它是一个伪数组,原型是对象Object

  • 可以通过下标[index]方式取值

function getValue(){
    console.log(arguments);//arguments就是传进来的4个参数组成的集合
    //当参数不确定时,就可以不设置参数,使用arguments接收
    //arguments.callee就是函数自己也就是getValue函数
    //匿名函数调用自己常用到arguments.callee
    //arguments.callee.caller是调用此函数的函数,也就是fn1函数
}
getValue(1,2,3,4);
function fn1(){
    getValue();
}
  • function getValue(){
    console.log(arguments);//arguments就是传进来的4个参数组成的集合
       //当参数不确定时,就可以不设置参数,使用arguments接收
       //arguments.callee就是函数自己也就是getValue函数
       //匿名函数调用自己常用到arguments.callee
       //arguments.callee.caller是调用此函数的函数,也就是fn1函数
    }
    getValue(1,2,3,4);
    function fn1(){
       getValue();
    }

    return返回值

    • 可以允许函数返回一个值,仅一个,也可以返回对象,数组,函数,函数体等

    • 如果在函数最后一句没有返回值的情况下,尽量不要写return

    • 函数没有return则返回undefined

return break continue区别

return 只能使用在函数中,函数外不能使用,无视任何内容直接跳出函数

break 用于switch或者循环语句中,跳出当前循环或者锚点循环,或者switch语句,循环外的语句继续执行

continue 仅跳出当前次循环,继续下一次循环,只能用于循环语句中

//生成rgba随机颜色函数,带透明度
function randomColor(alpha){
            // 如果没有参数,随机
            alpha=alpha==undefined ? Math.random().toFixed(2) : alpha;
            // 传入的参数转换为数值
            alpha=Number(alpha);
            // 如果传入的参数是非数值,就让透明度为1
            if(isNaN(alpha))alpha=1;
            var color="rgba(";
            for(var i=0;i<3;i++){
                color+=parseInt(Math.random()*256)+",";
            }
            color+=alpha+")";
            return color;
        }

四、回调函数,递归

递归或者回调的次数过多,没有阻止递归或者回调的条件,会造成堆栈溢出

1、回调函数

function fn1(f){
    f()//这里f函数称为回调的函数
}
function fn2(){
    console.log("aaa");
}
fn1(fn2);

利用回调函数模拟一个简单红绿灯(控制台输出 红灯,绿灯这样)

function getLight(first,second,third){
            first(second,third);
        }

        function getRedLight(fn,fn1){
           var f=arguments.callee;
            var ids=setTimeout(function(){
                console.log("红灯");
                clearTimeout(ids);
                fn(fn1,f);
            },1000);
        }
        function getYellowLight(fn,fn1){
            var f=arguments.callee;
            var ids=setTimeout(function(){
                console.log("黄灯");
                clearTimeout(ids);
                fn(fn1,f);
            },1000);
        }
        function getGreenLight(fn,fn1){
            var f=arguments.callee;
            var ids=setTimeout(function(){
                console.log("绿灯");
                clearTimeout(ids);
                fn(fn1,f);
            },1000);
        }
        getLight(getGreenLight,getYellowLight,getRedLight);
//可以更改函数的回调顺序改变输出结果的顺序

2、递归

函数不断自己调用自己,这样就叫做函数的递归;

递归的本质是函数每次自执行都会复制出一个一样的函数执行,每个复制的函数都有自己的作用域,如没有递归结束,则函数下面语句不执行,知道递归结束后才执行后面语句

 var i=0;
 fn();
function fn(){
   i++;
    // console.log(i);
   if(i<4) fn(); //这里就是再递归,满足条件继续执行自己
   console.log(i);//注意此时会输出四次i=4;因为只有在上面递归完后,才能执行此语句
 } 

function fn(n){
   if(!n) n=1;
   n++;//2
   if(n<5)  fn1(n);//挂起不会往下执行
   return n;//2因为第一次进来n=1,n++之后为2,而递归是复制出一个函数执行,这里是把n作为参数带进去,那么n就是每个复制的函数的局部变量,都只能在自身函数内部调用,此时的fn函数也只能调用到自己的局部变量,也就是n=2;
}
fn();//函数运行完之后,局部变量会被销毁

function fn(n){
   if(!n) n=1;
   n++;//2
   if(n<5) return fn1(n);//挂起不会往下执行,这里使用return把每次复制函数的结果返回给到上一个复制的函数,就会把变量n一步一步向上返回,直到返回给原函数,所以此时return  n 会输出5
   return n; //5

 

标签:function,函数,作用域,JavaScript,笔记,arguments,var,fn
来源: https://www.cnblogs.com/chen52125/p/16387672.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有