继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

你不知道的javascript---函数作用域

王小仙
关注TA
已关注
手记 3
粉丝 19
获赞 127

‘你不知道的javascript’------笔记 之 函数作用域

距离上一次写文章好长时间了,具体多长时间呢,时间的长度大概就是这段时间足够你找到一个女朋友了,,不知道大家都找到女朋友了吗,,反正我是没找到,哎,,真够愁人的,,哈哈,,
于是就跑来写文章,来和大家一起来交流以下javascript中的函数作用域,,来缓解我内心无比的悲伤,,哈哈大笑,,入正题:函数作用域

1. 函数作用域的概念

我们前面已经详细的论述了作用域,,那么函数的作用域概念也就显而易见了,

我们创建一个函数,,那么我们就创建了一个作用域,,这个作用域完全属于这个函数,
(我们其实理解这些完全没有用,我只是象征性的写一下,我们来看一下实例:);

1) 一个关于函数作用域的实例:

function foo(){
    var a = 1;
    function bar(){
        var b = 2;
        console.log(b)           
    }
    bar();                                                                 
}
foo();                     //执行 foo 函数,然后在 foo 函数内部成功调用了bar()函数
bar();                     //出错,
console.log(a);            //出错

我们可以对上面的函数做一个简单的分析:

  1. 首先我们调用函数 foo ,然后函数 foo 中成功调用函数 bar 然后打印出 b ,没有一点问 题
  2. 然后我们试图在外部作用域中调用函数 bar ,出错,这说明函数 bar 并不属于这个作用域,,函数 bar 是属于函数 foo 所创建的作用域de,,
  3. 我们试图在外部打印 a ,结果,,你知道的,,哈
  4. 这个例子我们更清楚的理解了函数作用域,但是并没有让人眼前一亮,,并不能给我们的学习带来什么启示,,那我们接下来看看函数作用域的两个功能,,希望可以帮助到大家: 2.函数作用于的两个实用功能:

    1) 隐藏内部实现,对代码进行封装

    首先是一个概念:

最小特权原则:就是说我们在实际开发中,我们应该最小限度的暴露必要的内容,我们
应该尽量少的使用全局变量 ,函数。,

然后是一个例子:

function num(a){
    b = a + num0(a);
    console.log(b);
}

function num0(a){
    return a-1;
}

var b;
num(6);
  1. 我们首先知道 变量 b , num0 是函数 num 内部需要的,,
  2. 但是我们把b , num0 全部定义在了全局作用域中,,这就造成了一定的混乱性,,我们函数 num 需要的 b , num0 有可能会与全局作用域中的变量函数同名,,或者我们全局作用域中也需要一个同名不同功能的的函数,这样就不好了,,(你也许会说我们可以换一个名字啊,但是那样会减低代码的可读性);
  3. 我们对上面的代码进行改造:
function num(a){
    var b = a + num0(a);
    console.log(b);

    function num0(a){
        return a-1;
    }
}

num(6);
// 这样是不是很好的封装了我们的代码,符合最小特权原则

2) 规避冲突

//例子
function foo(){
    function bar(a){
        i = 3;                           //没有声明,这里使用的是父作用域中的 i
        console.log(a + i);
    }
    for(var i=0; i<10; i++){          //当调用函数 bar 时,这里的 i 值会被更改
        bar(i*2);                     //i 永远也不会大于10了 
    }
}

foo();                     //最终这个函数是个无限循环
  1. 我们更改一下这一个函数
function foo(){
    function bar(a){
       var i = 3;                      //我们在这个函数内部声明自己的变量 i 
                              // 这样我们在为 i 赋值时就避免了改变父作用域中的 i
        console.log(a + i);
    }
    for(var i=0; i<10; i++){        
        bar(i*2);                  
    }
}

foo();                     //最终这个函数运行非常好

看完了函数作用域的两个功能,我们在来看下面一个非常重要的知识点:

3.深入:

1) 一个例子开始

var a = 2;
function foo(){
    var a = 3;
    console.log(a);          // 3 
}
foo();
console.log(a);         //2
  1. 首先我要说以下我们函数要实现的功能是 输出两个 a ,一个等于3 ,一个等于2
  2. 这段代码是不是很完美,,我们成功的运用函数作用于的功能避免了变量的冲突;
  3. bu ,你错了,,你在全局作用域中声明了 foo ,这是一个小小的遗憾, foo 会把全局给污染了,这不是我们想要的(注:我们举这个例子只是为了引出‘立即执行函数表达式’)

  4. 我们来看一下解决的方法(把 foo 也隐藏起来) 下面非常重要
var a = 2;

//立即执行函数表达式
(function foo(){
    var a = 3;
    console.log(a);         //3
})()               //我们这样定义一个函数
                   //1.他会自动执行  2.很好的隐藏了自己
console.log(a);        //2

function foo(){
    console.log(6);
}
foo()   //非常 6 的执行了自己

看了上面,,是不是感觉很好(感觉女朋友也不是那么的重要了,哈哈,),
我们再来看看 立即执行函数的其他的一些形式:

// 1.匿名的立即执行函数
(function(){
    console.log(6);
})();

// 2. 带有参数的
(function foo(a){         //在这里定义参数
    console.log(a)
}) (6)                //在这里传入 值

// 3. 传入yi个函数
var a = 2;
(function foo(def){               
    def(window);
})(function def(global){        //传入一个函数
    console.log(global.a);       // 2
})

2) 最后,我们来稍微看一下匿名函数:

setTimeout( function(){          //这里就是一个匿名函数  ,
                                 // 就是没有名字的函数,,
                                 // 我们在写代码的时候,尽量少的使用匿名函数,
                                 // 这样方便我们日后认出我们自己的代码,,
    console.log(6);
} ,2000);

好了,,就这样吧,,

打开App,阅读手记
21人推荐
发表评论
随时随地看视频慕课网APP

热门评论

其实还是有点懵了  不是很懂

查看全部评论