函数作用域和块作用域
我司因工作需求,把我这个实习生的戴尔换成了Mac,属实有点兴奋。今天本来休息,但本着珍惜时间的想法,还是来公司充实一下自己,整个公司就我一个人,特别安静,就我一个人键盘声,哈哈。用了两个小时配置了基础的开发环境,又回顾了一下第三章,吃饭前写一篇笔记。
1.函数中的作用域和隐藏内部实现
我认为这部分的关键有以下几点:
- javaScript具有基于函数的作用域,这是毋庸置疑的,这也意味着每声明一个函数都会为自身创建一个气泡(词法作用域中提到过)。
- 对函数的传统认知就是先声明一个函数,然后再向里面添加代码。但是我们如果逆向思维去思考,会有不一样的启示:我们从所写的代码中挑出了一个任意的片段,然后用函数声明对它进行包装,实际上就是把这些代码“隐藏”起来了。(外部函数永远无法获取内部函数定义的变量,内部函数将其变量私有化。)
- 规避冲突,防止污染。
- 全局命名空间
通常我们创建一个对象,这个对象便是一个命名空间,我们可以在其中写一些方法,之后点调用即可。var eatFood = { food : 'apple', eatIt(){ // ... }, getFood(){ // ... } } - 模块化开发
- 全局命名空间
2.函数作用域
```
var a = 2;
function foo(){
var a = 3;
console.log(a) //3
}
console.log(a) // 2
foo()
```
在上述代码中,我们利用函数作用域的特性,实现了“隐藏”了foo函数中的a属性,但是,
我们必须用函数将其包裹,给定一个函数名,之后在调用它。如果函数不需要函数名,
并且能够自动运行,那就太理想啦!而JS为我们提供了解决方案————立即执行函数。
-
函数表达式是啥玩意儿?
个人理解:如果声明中function是第一个单词,那就是函数声明,否则就是函数表达式
(function foo(){ //... }) 函数表达式 +function foo(){ //... } 函数表达式 function(){ //... } 函数声明务必区分函数声明和函数表达式,这是十分重要的
-
具名和匿名
-
匿名函数表达式
(function(){ //... })
注意点:函数表达式可以匿名,而函数声明坚决不可以!
-
匿名的优缺点:
优点:
- 不需要为函数名创建一个变量,不会“污染”所在作用域。
缺点:
- 匿名函数在栈中不会显示出有意义的函数名,很难调试与调用。
- 如果没有函数名,当函数需要引用自身时只能使用arguments.callee。
- 被省略的函数名往往可以大幅增加代码可读性。
始终给函数表达式命名是一个最佳实践
-
-
立即执行函数表达式(IIFE)
写法: (function(){ //... }(param)) 或者 (function(){ //... })(param)
3.块作用域
- 啥是块作用域呢???
{
//...
}
{
//...
}
这俩玩意儿,就是俩单独的块作用域!
-
其实在ES6到来之前呢,JS已经有了使用块作用域的情景。
with和try/catch
with在之前我们讨论过它,它可以从对象中创建出一个新的作用域,而这个作用域仅仅在with声明中有效。
try{ ... }catch(error){ a️ }
说出来你可能不相信,如果你能捕获到error,那么这个error只能在之后的{}中使用,在其他地方,你根本获取不到!
- let
随着ES6的到来,引入了新的let关键字,提供了除了var以外的另一种变量声明的方式。
这个let,特殊的很,它可以为其声明的变量劫持(识别)所在块级作用域,但是,let声明的变量不会进行提升,并且在同一作用域中不能重复声明同一个变量,之后我们会讨论它的更多特性,不要着急。
{
var a = 'a';
let b = 'b';
}
console.log(a) // 'a'
console.log(b) // b is not defined
var声明的变量无法识别块级作用域,而let声明的变量是ok的。
当for循环碰到let,会发生什么呢?
for(let i = 0;i<10;i++){
let i = 1 // 不会报错
// 在for循环中,存在父子作用域
// for循环头部的let不仅将i绑定到for循环的块中
// 事实上,它将其重新绑定到循环的每一个迭代中
}
下面通过另一种方式来说明每次迭代时进行重新绑定的行为:
{
let j;
for(j=0;j<10;j++){
let i = j;
console.log(i)
}
}
- const
除了let之外,ES6还引入了另一种声明变量的方式:const,同样可以用来创建块作用域变量,但它的值是固定的,准确的来说,地址是固定的。