Web前端之路让前端飞

js进阶学习笔记(二) -- 作用域以及变量提升

2017-07-13  本文已影响44人  一二三kkxx

一 初步了解作用域

在了解作用域之前,先来看一个问题;
var xixi= 222;在js处理这句话的时候,会发生什么呢?

二 函数作用域

var xi = '外部';
(function foo(global){//这里可以将后面传来的参数重新命名;
var xi = '内部';
console.log(xi) //'内部'
console.log(global.xi) //内部
})(window) //这里只要把window对象作为一个参数传给封装函数就行了.
console.log(xi); //'外部'

  **很多框架源码都用了这个方式来解决诸如防止undefined被篡改等情况**
  **函数是js中最常见的作用域单元**
  
###三 提升
直觉上,我们会认为js在执行代码的时候是由上到下一步一步执行的,但是实际上并不完全是这样
我们先看看一段代码
```java
a = 2;
var a;
console.log(a); //2

这句话的代码等同于

var a;
a= 2;
console.log(2)

再来看一段代码:

console.log(a);//undefined
var a = 2;

这段代码等同于:

var a;
console.log(a);
a = 2;

在这段代码里到底发生了什么呢?

js的作用域基本上都是词法作用域;什么是词法作用域呢?就是定义在词法阶段的作用域,是由你在写代码的时候将变量和作用域写在哪来决定的.大部分情况下词法作用域是不变的.

我们之前提到过,编译器第一个工作就是把代码解析成词法单元,然后语法分析成语法树;在这期间,编译器基本能够知道标识符是在哪声明以及是怎么声明的.它会用合适的作用域将他们关联起来.
作用域编译.jpg

回到我们刚刚的代码;

 console.log(a);//undefined
 var a = 2;

在编译阶段,会执行var a;;剩余的a = 2会留在原地等待执行;因此等同于

 var a;
 console.log(a);
 a = 2;

在这个阶段,变量声明会从他们代码所在的位置移动到最顶层更,这个过程就叫做提升;

函数声明和变量声明都会被提升,但是,函数会首先被提升.然后才是变量;(值得注意的是,函数声明提升的时候,函数体一同被提升;函数表达式的函数体则不提升;)

foo(); // 1
var foo;//尽管此变量声明在function foo()之前,但是因为函数优先
//foo变量声明就会变成重复声明,忽略;
function foo(){
console.log(1);
}
foo = function(){
console.log(2);
}

这段代码会被引擎理解为:

function foo(){
console.log(1)
}
foo();
foo = function(){
console.log(2)
}

虽然var重复声明会被忽略,但是后面的函数声明会覆盖前面的

foo(); // 3
function foo(){
    console.log(1);
}
var foo = function(){
    console.log(2);
}
function foo(){ //覆盖了之前的function foo();
    console.log(3);
}
上一篇下一篇

猜你喜欢

热点阅读