你不知道的Javascript之作用域

什么作用域

根据名称查找变量的一套规则,用于确定在何处以及如何查找变量(标识符);

如果查找的目的是对变量进行赋值 则用LHS查询

如果获取变量的值,则用RHS查询

//持续更新。。。。。。。

栗子:

 console.log(a)

其中对a是一个RHS引用,查找并取得a的值 传给 console。log

a=2

对LHS引用,不关心当前值是什么,只关心 =2 赋值给 a;

  function foo(a)
              {
                  console.log(a)//2
              }
              foo(2)

说明:最后一行foo()函数调用要对foo进行RHS查询,去找foo的值,代码中隐藏式 a=2 2会分配给参数a 为了给参数a分配值 需要进行一次LHS的查询

 

词法作用域:

作用域工作模式二种:
1.词法作用域
词法化的过程会对源码中的字符进行检查,如果有状态的解析过程,还会赋予单词含义;
定义在词法阶段的作用域,由写代码时候将变量与块作用域写在哪里决定;
考虑以下代码:
function foo(a)
{
var b = a*2;
function bar(c)
{
console.log(a,b,c)
}
bar(b*3)
}
foo(2);
无论函数在哪里调用,也无论被它如何调用,它的词法作用域都只由函数被声明时所处的位置决定;

2.动态作用域

函数作用域

函数作用域是指属于这个函数的全部变量都可以在整个函数的范围内使用及复用
外部作用域无法访问包装函数内部的任何内容

区分函数声明及表达式最简单的方法是function 关键词出现在声明中的位置;
函数声明以(function 而不是以function...开始 函数会被当作函数表达式来处理
如果function是声明中的第一个词,那么就是函数声明,否则就是一个函数表达式;
立即执行函数 又称 IIFE; 表达式: (function(){.....})
块作用域:
for (var i = 0; i < Things.length; i++) {
......
//do something;
}
for开头定义 变量i ,忽略了外部作用域可以绑定它的事实 ;

提升

我们习惯把 var a = 2 看作一个声明,而实际上javascript引擎会分开 var a 与 = 2 单独2个声明,第一个阶段是编译,第二个阶段是执行;

所有声明(变量或函数),都会被移动各自的作用域最顶部,被称为提升;

任何声明在某个作用域内的变量,将附属于这个作用域;
编译阶段的一部分工作就是找到所有的声明,并用合适的作用域将他们关联起来;
var a; a=2; console.log(a); 其中第一部分编译 第二部分是执行
类似流程: var a ; console.log(a); a=2;;
先有声明再有赋值;

只有声明会被提升,而赋值与其他运行逻辑会被留在原地;

函数声明会提升,表达式不会,
foo(); //错误 typeError foo没有被赋值;如果它是一个函数声明 而不是函数表达式那它就会被赋值

var foo = function bar()
{
//do something;
}
即使是具名函数,名称标识符在赋值之前也无法在所在作用域中使用;
foo();
bar();
var foo = function bar()
{
console.log("我可以用码");
}
代码提升之后
var foo;
foo();
bar();
foo = function ()
{
var bar = ...self....;
//.....
}

函数声明与变量声明都会被提升; 但是函数会首先被提升,然后才是变量;

 1 foo(); //结果是1
 2 var foo; //变量声明
 3 function foo() //函数声明
 4 {
 5 console.log(1);
 6 }
 7 foo = function()
 8 {
 9 console.log(2);
10 }
11 引擎的理解是:
12 function foo()
13 {
14 console.log(1);
15 }
16 foo();
17 foo = function()
18 {
19 console.log(2);
20 }

 

posted @ 2017-02-17 09:41  h5monkey  阅读(138)  评论(0编辑  收藏  举报