“提升”以及函数声明和函数表达式

2017-02-03  本文已影响0人  _v_xw

一. 函数声明

// 函数声明
function funDeclaration(type){ return type==="Declaration"; }

二. 函数表达式

// 函数表达式
var funExpression = function(type){ return type==="Expression"; }
 
用函数声明创建的函数funDeclaration可以在funDeclaration定义之前就进行调用;而用函数表达式创建的funExpression函数不能在funExpression被赋值之前进行调用。
为什么会这样呢?!这就要理解Javascript Function两种类型的区别:用函数声明创建的函数可以在函数解析后调用(解析时进行等逻辑处理);而用函数表达式创建的函数是在运行时进行赋值,且要等到表达式赋值完成后才能调用。
这个区别看似微小,但在某些情况下确实是一个难以发现的陷阱。出现这个陷阱的本质原因体现在这两种类型在Javascript function hoisting(函数提升)和运行时机(解析时/运行时)上的差异

三. 提升

谁会被提升

变量声明:使用var ,let ,const关键字
函数声明:使用function(){......}语法
类声明:使用class关键字

  1. 函数声明在函数作用域内创建并初始化一个变量。默认情况下,声明但是未初始化的变量的值是undefined。
  2. javascript并没有严格遵循这个顺序,因此提供了更多的灵活性。比如:函数的使用可以在声明之前。(目前就这个)
var foo;
function foo(){
    console.log(1);
}

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

会输出1二不是2!这个代码片段会被引擎理解为如下形式:

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


注意:var foo尽管出现在 function foo()...的声明之前,但它是重复的声明(因此被忽略了),因为函数声明会被提升到普通变量之前。

尽管**重复的var** 声明会被忽略掉,但出现在后面的函数声明还是可以**覆盖**前面的。

##四. 总结
无论作用域中的声明出现在什么地方,都将在代码本身被执行前首先进行处理。可以将这个过程形象地想象成所有的声明(变量和函数)都会被“移动”到各自作用域的最顶端,这个过程被称为提升。

声明本身会被提升,而包括函数表达式的赋值在内的赋值操作并不会提升。要注意避免重复声明,特别是当普通的var 声明和函数声明混合在一起的时候,否则会引起很多危险的问题!

**参考至《你不知道的Javascript 上卷》**
上一篇下一篇

猜你喜欢

热点阅读