函数声明 和 var声明的优先级

1.变量声明 提高:函数

console.log(typeof a); // undefined
 
var a = 1; console.log(typeof a); // number

  执行过程 至关于:spa

var a; console.log(typeof a); // undefined
 a = 1; console.log(typeof a); // number

 

2.函数声明 提高:code

  函数声明 的提高是一个 总体提高的过程blog

demo:开发

console.log(typeof a); // function
 
function a(){} console.log(typeof a); // function

  如上的demo,足能够证实,这一结论;假如不是总体提高,是相似于 var变量声明的提高的方式,应该会如 var变量声明的方式的输出方式相同, 先输出 undefined,再输出 function;io

 

3.无所谓 函数声明优先 or 变量声明优先console

  那么,又来了个问题,既然 var声明 和 函数声明 都有提高机制,那么它俩的声明提高优先级是什么样子呢;编译

为了论证这个我在网上看了好多资料,也查了好多书籍,你们一直认为 函数声明提高 优先于 变量声明提高,可是我发现,你们的论据都不够充分;好比以下的一个论证:function

a(); // 1

var a; function a() { console.log(1); } a = function() { console.log(2); } a(); // 2

 

  而后,也描述了它的执行过程,至关于:class

 解释 A:

function a(){ console.log(1); } var a; // 遇到没有赋值的同名声明,忽略,不作操做;至关于什么都没有作
 a(); // 1
 a = function(){ console.log(2); } a(); // 2

 

  若是如上的操做的解释,也能够经过,能够论证出 “函数声明提高 优先于 变量声明提高”;可是,按以下的理解应该也是解释的通的啊:

解释 B:

// 注意 var a 和 function a声明都会在栈空间开辟存储空间,而且 是占用同一块name为 a的空间;

var a; // 此时 a 没有赋值, 是个空的栈空间值
 
function a(){ // 找到 name为a的栈空间,给它赋值 function(){console.log(1)}, 至关于覆盖
    console.log(1); } a(); // 1
 a = function(){ console.log(2); } a(); // 2

 

  看到了吧,如上的 论述也是行的通的,可是论述出来的结果 是“变量声明提高 优先于 函数声明提高”;这就尴尬了。。。

其实呢,我仔细想了一下,其实 谁先声明提高的都无所谓,由于 “var a 和 function a声明都会在栈空间开辟存储空间,而且开辟的是同一块 name为 a的空间,也就是说它们用的是同一块空间”;

 

4.函数声明先赋值,变量声明执行到赋值语句才赋值

  由于两种声明方式共同操做一块栈空间,因此,主要看是谁先赋值的,咱们再看一个例子:

console.log(typeof a); // function

var a = 1; function a(){} console.log(typeof a); // number

 

  这就看的出来了,经过上边的这个demo, 明显能够看出来,应该 函数声明先赋值的,它是在执行上下文的执行阶段一开始的时候就已经进行了赋值操做,因此 最开始 typeof a 能够获得 function;而,变量声明 是要执行到赋值语句的时候才进行的赋值,因此 最后 typeof a 获得是 number;

  若是不是这样的话,咱们不妨作下假设:

  假设1:都是最先赋值,无论谁先赋值,结果以下:

/* ->var 声明; ->函数声明; ->var 赋值; ->函数赋值: ->console.log(typeof a); // function 或者 number ->console.log(typeof a); // function 或者 number */

 

  结果如上,最后输出不是同是 function 就是同是 number, 不符合正确输出;

  假设2:都是执行到赋值语句的时候才赋值,不管 两种声明 谁前谁后,结果以下:

/* ->var 声明; ->函数声明; ->console.log(typeof a); // undefined ->赋值操做: ->console.log(typeof a); // function 或者 number */

 

  结果如上,第一个输出必定都是 undefined, 不符合正确输出;

  假设3:经过 (1) 和 (2)的不经过,那么只剩下一种可能了,都是先声明,而后一个先赋值,一个到 执行语句的时候才赋值;也就推测出了咱们的结论:"函数声明先赋值,变量声明直到赋值语句的时候才赋值";执行过程以下:

/* -> a 声明;// 由于同用一个栈空间,因此无所谓谁先声明 -> 函数声明赋值 ->console.log(typeof a); // function ->变量声明赋值: ->console.log(typeof a); // number */

  符合正确输出的结果;因此结论成立;

  其实 函数的总体提高方式就已经论证了这一点,不管是如 解释 A 函数提高优先 + 忽略未赋值的 var 声明, 仍是如 解释 B变量声明提高优先 + 函数后声明覆盖var 声明,最后都是在同一个栈空间上进行的操做,并没有所谓,重要的是谁先进行的赋值操做;还有就是如上的这种 变量声明和函数声明是同名的用法,尽可能不要在正式开发中使用,很容易就出现难以排查的异常;

 

4.总结

  *->1.函数声明 和 变量声明都有声明提高机制

  *->2.函数声明 是总体提高的方式,来进行的声明提高;

  *->3.函数声明 和 变量声明,无所谓谁优先于谁,都是在预编译阶段进行的;(根据第4点的总结,也能够理解为 函数声明优先于变量声明)

  *->4.函数声明赋值 要早于 函数声明赋值

    **->.函数声明赋值,是在执行上下文的开始阶段进行的;

    **->.变量声明赋值,是在执行到赋值语句的时候进行的赋值;

  

 

 

 原创:转载注明出处,谢谢 :)

相关文章
相关标签/搜索