一. Function

什么是: 保存一段可重用的代码段的程序结构
 何时: 只要一段代码可能被反复使用时。
 如何: 3种: 
  1. 用声明方式: 
    function 函数名(形参列表){
      函数体
      return 返回值
    }
    问题: 会被声明提前(hoist)
  2. 用赋值方式: 
    var函数名=function (形参列表){
      函数体
      return 返回值
    }
    揭示了: 函数也是一个对象
            函数名其实只是一个变量
            函数名变量通过对象地址引用着函数对象
    优点: 不会被声明提前——因为赋值留在原地
  3. 用new: 
    var fun=new Function("形参","形参",...,"函数体")

二. 重载:(overload)

什么是: 相同函数名不同参数列表的多个函数,在调用时,可根据传入参数的不同,动态选择匹配的函数执行
  为什么: 减少API的数量,减轻调用者的负担
  何时: 1件事,可根据给的参数不同,执行不同的操作时
  如何: 
   问题: js不支持重载语法!
   因为: js不允许多个同名函数同时存在,最后一个同名函数会覆盖之前所有。
   解决: 借助arguments对象
    什么是arguments: 每个函数内自带的
                     专门接受所有传入函数的参数值的
                     类数组对象
    何时: 将来不确定调用函数时会传入几个参数值
    如何: 
     1. 不用创建,直接使用
     2. vs 数组: 相同: 1. 下标,  2. .length属性, 3. for遍历
           不同: 类型不同,API不通用!

三. 匿名函数:

什么是: 创建函数时不制定函数名的函数
  为什么: 2个目的: 
   1. 节约内存
   2. 临时使用划分临时作用域
  何时: 只要一个函数,只使用一次时,都不起名
  如何: 2种: 
   1. 回调函数: 
    什么是: 你定义的但是交给别的函数去调用
      比如: arr.sort(function(a,b){return a-b})
           xhr.onreadystatechange=function(res){...}
           str.replace(/正则/,function(kword){ ... })
   2. 匿名函数自调: 
    什么是: 定义函数后,立刻调用自己
    为什么: 全局变量极容易造成全局污染
      全局污染: 一个变量不再使用,但空间不释放
    何时: 划分临时作用域,避免使用全局变量
    如何: (function(形参列表){
           ... ...
         })(实参列表)
    总结: 1. 今后禁止使用全局变量
         2. 所有js代码都应该用匿名函数自调包裹起来

四.作用域和作用域链:

作用域(scope):  
	   什么是: 一个变量的可用范围
			其实, 每个作用域都是一个保存变量的对象
	   为什么: 防止内外变量之间互相干扰
   包括: 2种: 
	    1. 全局作用域: 
	     什么是: 保存全局变量,从程序任何位置都可访问的作用域
	       全局变量: 随处可用,可反复使用
	    2. 函数作用域: 
	     什么是: 保存局部变量,仅函数内可用的作用域
	       局部变量: 仅函数内可用,不可反复使用
	    强调: js中没有块级作用域: 
	     比如: if...else  for... 不是作用域
     
 原理: 
   1. 开始执行前: 
		1. 创建执行环境栈数组: 用于记录将来调用的函数
	    2. 调用浏览器软件的主程序main()函数
	    3. main()函数会创建并引用window对象
	       此时window对象中已经包含了很对内置的函数和对象: alert()  prompt()   document    console
   2. 定义函数时: 
	    1. 创建函数对象
	    2. 在window中添加函数名变量
	    3. 函数名变量引用函数对象
	    4. 函数对象用scope属性引用回window
  3. 函数调用时: 
	    1. 在执行环境栈数组中添加本次函数调用的记录
	    2. 为本次函数调用临时创建函数作用域对象
	       函数作用域对象的parent属性指向window
	    3. 在函数作用域对象中临时创建局部变量
	    4. 函数执行过程中: 
	      优先在函数作用域对象中查找变量使用
	      如果找不到才被迫去window找
4. 函数调用后: 
    本次函数调用的记录出栈
       导致函数作用域对象释放
          导致局部变量一同释放——局部变量不可重用

五. 作用域链scope chain
什么是: 由多级作用域对象,逐级引用形成的链式结构
保存着所有的变量: 全局变量和局部变量
控制着变量的使用顺序: 先局部,后全局

六.闭包:

什么是: 既重用变量,又保护变量不被污染的一种机制
  为什么:
   全局变量: 
     优: 可反复使用
     缺: 随处可用
   局部变量:
     优: 仅函数内可用
     缺: 不可重用
  何时: 为一个函数永久绑定一个专属的可重用变量时
  如何: 3步: 
   1. 用外层函数包裹要保护的变量和内层函数
   2. 外层函数将内层函数对象返回到外部
   3. 调用外层函数,获得内层函数对象,保存在变量中
  闭包形成的原因: 外层函数的作用域对象在调用后无法释放
  缺点: 闭包比普通函数多占用内存
  笔试: 画简图: 
   1. 找受保护的变量
   2. 找外层函数共向外抛出了几个内层函数对象: 
	3种情况:
    1. return function(){ ... }
    2. 直接给全局变量赋值一个函数!
    3. 将函数包裹在对象或数组中返回