闭包

当函数可以记住并访问所在的作用域(全局作用域除外)时,就产生了闭包,即使函数是在当前作用域之外执行。

作用域链

作用域链,是由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。

运行环境

  • 全局环境
  • 函数环境
  • eval

当代码在执行过程中,遇到以上三种情况,都会生成一个执行上下文,放入栈中,而处于栈顶的上下文执行完毕之后,就会自动出栈,栈底永远都是全局上下文,而栈顶就是当前正在执行的上下文。

全局上下文在浏览器窗口关闭后出栈。

变量对象

  • 检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖。

  • 检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。

  • 全局上下文有一个特殊的地方,它的变量对象,就是window对象。而这个特殊,在this指向上也同样适用,this也是指向window。

this

this的指向,是在函数被调用的时候确定的,在函数执行过程中,this一旦被确定,就不可更改了。

  • 如果调用者函数,被某一个对象所拥有,那么该函数在调用时,内部的this指向该对象。
  • 如果函数独立调用,那么该函数内部的this,则指向undefined,如果在严格模式,this则指向window。
  • 如果是构造函数,那么this指向实例化对象。
  • call、apply可以改变this的指向

函数式编程

函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。

面向对象

构造函数中

属性与方法为当前实例单独拥有,只能被当前实例访问,并且每声明一个实例,其中的方法都会被重新创建一次。

原型中

属性与方法为所有实例共同拥有,可以被所有实例访问,新声明实例不会重复创建方法。

模块作用域中

属性和方法不能被任何实例访问,但是能被内部方法访问,新声明的实例,不会重复创建相同的方法。