函数作用域:属于这个函数的全部变量都可以在整个函数的范围内使用及复用。

函数是 JavaScript中最常见的作用域单元。本质上,声明在一个函数内部的变量或函数会在所处的作用域中“隐藏”起来,这是有意为之的良好软件的设计原则。

最小特权原则

最小授权或最小暴露原则

这个原则指在软件设计中,应该最小限度地暴露必要内容,而将其他内容都“隐藏”起来。

函数声明和函数表达式

区分函数声明和表达式:如果 function 是声明中的第一个词,那就就是一个函数声明,否则就是一个函数表达式。

函数声明和函数表达式之间最重要的区别就是它们的名称标识符将会绑定在何处。

匿名和具名

函数表达式可以是匿名的,而函数声明则不可以省略函数名。

匿名的缺点:

  1. 匿名函数在栈追踪中不会显示有意义的函数名,使得调试很困难。

  2. 如果没有函数名,当函数需要引用自身时只能使用已经过期的 arguments.callee 引用

  3. 匿名函数省略了对于代码的可读性/可理解性很重要的函数名。

立即执行函数表达式

立即执行函数表达式(Immediately Invoked Function Expression,IIFE)

将函数包含在一对 () 内部,因此成为了一个表达式,通过在末尾加上另外一个 () 可以立即执行这个函数

1(function IIFE(){
2  console.log('IIFE')
3})()

函数名对 IIFE 不是必须的,IIFE 最常见的用法就是使用一个匿名函数表达式。

建议使用“具名”表达式,虽然并不常见,但是具有匿名表达式的所有优势,是值得推广的实践。

相较于传统的IIFE形式,还有一种改进形式:将调用的 () 括号引入到包装的 () 括号中,两种形式在功能上是一致的。

1(function IIFE(){
2  console.log('IIFE')
3}())

IIFE的进阶用法:

  1. 把它们当作函数调用并传递参数进去。

    1(function IIFE(global){
    2  ...
    3})(window)
  2. 解决undefined标识符的默认值被错误覆盖导致的异常(不常见)。

    1// 将参数命名为undefined,但是在对应位置不传入任何参数,这样就保证代码块中的 undefined标识符 的值是真的 undefined
    2(function IIFE(undefined){
    3  var a;
    4  console.log(a === undefined); // true
    5})()
  3. 倒置代码的运行顺序。

    1(function IIFE(def){
    2  def(window)
    3})(function def(global){
    4  ...
    5})