‘你不知道的javascript’------笔记 之 函数作用域
距离上一次写文章好长时间了,具体多长时间呢,时间的长度大概就是这段时间足够你找到一个女朋友了,,不知道大家都找到女朋友了吗,,反正我是没找到,哎,,真够愁人的,,哈哈,,
于是就跑来写文章,来和大家一起来交流以下javascript中的函数作用域,,来缓解我内心无比的悲伤,,哈哈大笑,,入正题:函数作用域
我们前面已经详细的论述了作用域,,那么函数的作用域概念也就显而易见了,
我们创建一个函数,,那么我们就创建了一个作用域,,这个作用域完全属于这个函数,
(我们其实理解这些完全没有用,我只是象征性的写一下,我们来看一下实例:);
1) 一个关于函数作用域的实例:
function foo(){
var a = 1;
function bar(){
var b = 2;
console.log(b)
}
bar();
}
foo(); //执行 foo 函数,然后在 foo 函数内部成功调用了bar()函数
bar(); //出错,
console.log(a); //出错
我们可以对上面的函数做一个简单的分析:
- 首先我们调用函数 foo ,然后函数 foo 中成功调用函数 bar 然后打印出 b ,没有一点问 题
- 然后我们试图在外部作用域中调用函数 bar ,出错,这说明函数 bar 并不属于这个作用域,,函数 bar 是属于函数 foo 所创建的作用域de,,
- 我们试图在外部打印 a ,结果,,你知道的,,哈
- 这个例子我们更清楚的理解了函数作用域,但是并没有让人眼前一亮,,并不能给我们的学习带来什么启示,,那我们接下来看看函数作用域的两个功能,,希望可以帮助到大家: 2.函数作用于的两个实用功能:
1) 隐藏内部实现,对代码进行封装
首先是一个概念:
最小特权原则:就是说我们在实际开发中,我们应该最小限度的暴露必要的内容,我们
应该尽量少的使用全局变量 ,函数。,
然后是一个例子:
function num(a){
b = a + num0(a);
console.log(b);
}
function num0(a){
return a-1;
}
var b;
num(6);
- 我们首先知道 变量 b , num0 是函数 num 内部需要的,,
- 但是我们把b , num0 全部定义在了全局作用域中,,这就造成了一定的混乱性,,我们函数 num 需要的 b , num0 有可能会与全局作用域中的变量函数同名,,或者我们全局作用域中也需要一个同名不同功能的的函数,这样就不好了,,(你也许会说我们可以换一个名字啊,但是那样会减低代码的可读性);
- 我们对上面的代码进行改造:
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(); //最终这个函数是个无限循环
- 我们更改一下这一个函数
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
- 首先我要说以下我们函数要实现的功能是 输出两个 a ,一个等于3 ,一个等于2
- 这段代码是不是很完美,,我们成功的运用函数作用于的功能避免了变量的冲突;
bu ,你错了,,你在全局作用域中声明了 foo ,这是一个小小的遗憾, foo 会把全局给污染了,这不是我们想要的(注:我们举这个例子只是为了引出‘立即执行函数表达式’)
- 我们来看一下解决的方法(把 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);
好了,,就这样吧,,
热门评论
其实还是有点懵了 不是很懂