iniaks / Heimerdinger

Personal Reading Notes
0 stars 0 forks source link

你所不知道的Javascript #2

Open iniaks opened 8 years ago

iniaks commented 8 years ago

读书笔记

iniaks commented 8 years ago

作用域

编译:

一套用来存储,调用变量的规则被称为作用域

JS不是提前编译的语言,传统编译语言在执行前有三个步骤:

JS引擎比这个要复杂的多,因为JS是边编译边执行,所以它花了大量的步骤来针对编译过程进行性能优化

LHS和RHS

当变量出现在赋值操作左侧时编译器会进行LHS(左侧)查询,出现在右侧时进行RHS(非左),这两种操作的含义为“赋值操作的左侧和右侧”,这并不等于“=操作符的左侧和右侧”。赋值操作有很多种形式

LHS代表着赋值操作的目标 RHS代表着赋值操作的源头

比如

function foo (a) {
   var b = a
  return a + b
}

var c = foo(2)

在这个例子中,有三处LHS查询: 为c查询,为a查询,以及为b查询 四处RHS查询: 为c赋值,为b赋值,为a+b中的a,b赋值

iniaks commented 8 years ago

词法作用域

词法作用域是定义在词法阶段的作用域,它由变量和块作用域在代码中的位置来决定。作用域查找会在找到第一个匹配的标示符时停止。

通过with和eval可以达到欺骗词法的目的,均不推荐使用,它们都会严重影响JS的性能

iniaks commented 8 years ago

函数作用域与块作用域

函数作用域:一个函数的所有变量都可以在整个函数的范围内使用及复用。

iniaks commented 8 years ago

提升

a = 2
var a
console.log(a) //输出2
console.log(a) //输出undefined
var a = 2
iniaks commented 8 years ago

作用域闭包

function foo () {
  var a = 2

  function bar () {
    console.log(a)
  }
  return bar
}

var baz = foo()
baz()

闭包使得函数可以继续访问定义时的词法作用域

function foo () {
  var a = 2

  function baz () {
    console.log(a)
  }
  bar(baz)
}

function bar(fn) {
  fn()
}

当函数在别处调用时都可以观察到闭包

本质上,无论何时,如果将函数当做第一级的值类型并到处传递,就可以观察到闭包

最基本和常见的例子:

for (var i=1; i<5; i++) {
  setTimeout( function timer() {
    console.log(i)
  }, i*1000)
}