js基础之变量声明提升

变量声明的提升

这是js特有的一个特点,其他语言都没有这个特点。有些程序员挺反感这个特点的。

我们现在先去改变变量的值,然后定义变量,由于JS有一个机制,叫做变量声明的提升,

javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面。

所以现在程序在执行前会已经看见这个程序中有一行定义变量,所以就会提升到程序开头去运行


1

2

3

4

5

6

7

8

9

var v = ‘hello‘;

(function(){

  console.log(v);

  var v = ‘world‘

})()

//结果为undefined


1

2

3

4

5

6

7

8

9

var v = ‘hello‘;

if(true){

  console.log(v);

  var v = ‘world‘

}

输出结果为”hello”,说明javascript是没有块级作用域的函数是JavaScript中唯一拥有自身作用域的结构。

因为javascript为动态语言,其变量并没有固定的类型,其存储空间大小会随初始化与赋值而变化,所以其变量的“定义”就不像传统的静态语言一样了,其定义显得无关紧要。

声明提升

当前作用域内的声明都会提升到作用域的最前面,包括变量和函数的声明


1

2

3

4

5

6

(function(){

  var a = "1";

  var f = function(){};

  var b = "2";

  var c = "3";

})();

变量a,f,b,c的声明会被提升到函数作用域的最前面,类似如下:


1

2

3

4

5

6

7

(function(){

  var a,f,b,c;

  a = "1";

  f = function(){};

  b = "2";

  c = "3";

})();

请注意函数表达式并没有被提升,这也是函数表达式与函数声明的区别。进一步看二者的区别:


1

2

3

4

5

6

7

8

9

(function(){

  //var f1,function f2(){}; //hoisting,被隐式提升的声明

  f1(); //ReferenceError: f1 is not defined

  f2();

  var f1 = function(){};

  function f2(){}

})();

上面代码中函数声明f2被提升,所以在前面调用f2是没问题的。虽然变量f1也被提升,

但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有声明是被提升的。

不写var

abc = 123;

        console.log(abc);//123

定义abc的时候没有写var,程序没有报错,说明这个abc变量真的已经被定义成功了。

不写var定义了一个全局变量,作用域是不能控制的

javascript中一个名字(name)以四种方式进入作用域(scope),其优先级顺序如下:
1、语言内置:所有的作用域中都有 this 和 arguments 关键字
2、形式参数:函数的参数在函数作用域中都是有效的
3、函数声明:形如function foo() {}
4、变量声明:形如var bar;

名字声明的优先级如上所示,也就是说如果一个变量的名字与函数的名字相同,那么函数的名字会覆盖变量的名字,

无论其在代码中的顺序如何。但名字的初始化却是按其在代码中书写的顺序进行的,不受以上优先级的影响。看代码:


1

2

3

4

5

6

7

8

9

(function(){

    var foo;

    console.log(typeof foo); //function

    

    function foo(){}

    foo = "foo";

    console.log(typeof foo); //string

})();

如果形式参数中有多个同名变量,那么最后一个同名参数会覆盖其他同名参数,即使最后一个同名参数并没有定义。

以上的名字解析优先级存在例外,比如可以覆盖语言内置的名字arguments。

命名函数表达式

可以像函数声明一样为函数表达式指定一个名字,但这并不会使函数表达式成为函数声明。命名函数表达式的名字不会进入名字空间,也不会被提升。


1

2

3

4

5

f();//TypeError: f is not a function

foo();//ReferenceError: foo is not defined

var f = function foo(){console.log(typeof foo);};

f();//function

foo();//ReferenceError: foo is not defined

命名函数表达式的名字只在该函数的作用域内部有效。

  

时间: 2024-08-29 00:38:28

js基础之变量声明提升的相关文章

JS中的变量声明提升

JS是一种脚本语言,和一些高级语言不同,它没有完整编译的过程,一般是边写边编译,这也是我们觉得脚本语言比其他语言加载快的原因,其实,JS中有变量声明提升这一机制.当JS在执行的时候会分为2个阶段,预解析,执行,当JS在执行的时候会将所有用var声明的变量以及关键字定义的函数进行提升(  function  fn(){......}  ),提升到当前作用域的最顶端,而赋值语句在原地等待执行,预解析后,再从上往下逐行解析代码.预解析遵循一些原则,下面一点一点的说明. 提到变量声明提升,就得结合作用域

js变量声明提升

1.变量提升 根据javascript的运行机制和javascript没有块级作用域这个特点,可以得出,变量会声明提升移至作用域 scope (全局域或者当前函数作用域) 顶部的. 变量声明提升至全局域 console.log(a); // undefined var a ="Hi"; 相当于 var a; // 变量提升到全局作用域 console.log(a); // 已声明变量a,但未初始化,固为undefined a="Hi"; 变量声明提升至当前函数域 v

js 函数和变量的提升

1. 函数的作用域: js中 ,函数的作用域为函数,而不是大括号. var hei = 123;if(true){ hei = 456;}console.log(hei);// 456; var hei = 123;if(true){ (function(){ var hei = 456;})(); }console.log(hei); // 123 函数内部可以用用函数外部的变量,而函数外部的不可以用函数内部的变量(可以用闭包实现效果,随后总结). (function(){ var hei =

[Effective JavaScript 笔记] 第12条:理解变量声明提升

js支持词法作用域,即除了极少的例外,对变量的引用会被绑定到声明变量最近的作用域中. js不支持块级作用域,即变量定义的作用域并不是离其最近的封闭语句或代码块,而是包含它们的函数. 不了解这个会产生一些微妙的bug. functon isWinner(palyer,others){ var highest=0; for(var i=0,n=others.length;i<n;i++){ var palyer=others[i]; if(player.score>highest){ highes

javascript变量声明提升

javascript变量声明提升(hoisting) javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面. 先看一段代码 1 2 3 4 5 var v = "hello"; (function(){   console.log(v);   var v = "world"; })(); 这段代码运行的结果是什么呢?答案是:undefined这段代码说明了两个问题,第一,funct

JS执行顺序-函数声明提升、匿名函数、函数表达式

大方向上: JS 是按照 代码块 进行 编译.执行 的. 学习至: 1.变量声明提升 2.新唐的博客 3.js中匿名函数的创建与调用方法分析 4.前端圣经 - 高程三 5.深入理解变量声明提升和函数声明提升 因为没有好好地分类.可能会比较杂.为了系统地学习,先了解几个概念. 一. <script> 区分的代码块. JS是按照代码块 编译 和 执行的.代码块间 相互独立,但是 变量和方法 共享. <script> alert('代码块一'); </script> <

JavaScript 变量声明提升

JavaScript 变量声明提升 一.变量提升的部分只是变量的声明,赋值语句和可执行的代码逻辑还保持在原地不动 二.在基本的语句(或者说代码块)中(比如:if语句.for语句.while语句.switch语句.for...in语句等),不存在变量声明提升 三.函数声明会提升,但是函数表达式的函数体就不会提升 1 fun(); // hello 2 function fun(){ 3 console.log("hello"); 4 } 5 // -------------- 6 //

深入理解变量声明提升和函数声明提升

变量声明提升 1.变量定义 可以使用var定义变量,变量如果没有赋值,那变量的初始值为undefined. 2.变量作用域 变量作用域指变量起作用的范围.变量分为全局变量和局部变量.全局变量在全局都拥有定义:而局部变量只能在函数内有效. 在函数体内,同名的局部变量或者参数的优先级会高于全局变量.也就是说,如果函数内存在和全局变量同名的局部变量或者参数,那么全局变量将会被局部变量覆盖. 所有不使用var定义的变量都视为全局变量 3.函数作用域和声明提前 JavaScript的函数作用是指在函数内声

函数声明的提升和变量声明提升

注:本文转自:http://blog.csdn.net/qq673318522/article/details/50810650仅做学习方便,没有任何商业目的: 变量声明提升 1.变量定义 可以使用var定义变量,变量如果没有赋值,那变量的初始值为undefined. 2.变量作用域 变量作用域指变量起作用的范围.变量分为全局变量和局部变量.全局变量在全局都拥有定义:而局部变量只能在函数内有效. 在函数体内,同名的局部变量或者参数的优先级会高于全局变量.也就是说,如果函数内存在和全局变量同名的局