深入理解JS中的变量及变量作用域

JS的变量有两种,“全局变量”和“局部变量”。

“全局变量”声明在函数外部,可供所有函数使用,(全局变量属于window)而“局部变量”声明在函数体内部,只能在定义该变量的函数体内使用。

1.全局变量:(1)直接在函数外部声明的变量   var a=3

(2)在任何位置上,声明变量时没有var关键字,而是直接赋值的变量均为全局变量     s=3

2.局部变量:(1)在函数内部声明的变量

(2)形参,参数变量天生就是局部变量

1 <script type="text/javascript">
2   function main() {  
3     n = 10;//这里的n为全局变量,可以被外部直接使用
4   }
5   main();
6   alert(n);
7 </script>

JS的作用有两种,“全局作用域”和“函数作用域”。

1.全局作用域:可以在程序的任何位置被访问

2.函数作用域:  仅能在函数调用时,内部被访问

注意:在函数体内,局部变量的优先级高于全局变量。

网上有一个很具有代表性的例子,在函数体外部和内部都申明了相同名字的变量,变量的作用域问题,例子如下:

 1 <script type="text/javascript">
 2   var n = 1;
 3   function test() {
 4     alert(n);  //这里的n并不是全局变量,原因是函数体第四行声明了一个重名的局部变量n,
 5                  //如果把第四行n的声明注释掉,那么这里的显示1,为全局变量。
 6                 //所以得出结论:全局变量a被局部变量a覆盖了。
 7               //说明了JS函数在test()在执行前,函数体内的变量a都指向了局部变量.
 8             //但本行输出的a在执行过程中还没有被赋值,所以显示undefined。
 9     n = 2;
10     alert(n);
11     var n; //本行声明局部变量a
12     alert(n);
13   }
14     test();
15     alert(n);
16 </script>

上面代码的结果为:undefined 2 2 1; 原因就是函数体外部和内部都申明了相同名字的变量时,局部变量覆盖了全局变量。

外部怎么读取函数体内部的局部变量呢?

一般来说,只有函数体内部可以直接得到外部的全局变量,但是外部要得到函数体内部的局部变量是不行的。但是,通过在函数体内部再定义一个函数返回局部变量,再从外部调用函数就能实现了。

 1 <script type="text/javascript">
 2   function f1() {    
 3     var n = 10;    
 4     function f2() {//在f1()内部再定义f2(),通过f2()访问f1()中的局部变量      
 5       alert(n);    
 6     }    
 7     return f2;//返回f1()局部变量n
 8   }  
 9   var result = f1(); //在外部调用f1()函数,就能获取局部变量n的值
10   result(); // 10,即为n的值
11 </script>

函数中变量的声明提升

在程序执行前或函数调用前,将var声明的变量和function声明的函数提升到当前作用域的顶部集中创建。

请看下面的例子:

1 var v = "hello";
2 (function(){
3   console.log(v);
4   var v = "world";
5 })();    结果为undefined
1 var v = "hello";
2 if(true){
3   console.log(v);
4   var v = "world";
5 }     结果为hello

上面的代码说明了3个问题:1,function作用域里的变量v遮盖了全局作用域变量v

             2,在function作用域内,变量v的声明被提升了

3,javascript是没有块级作用域的函数是JavaScript中唯一拥有自身作用域的结构

上面的代码相当于:

1 var v = "hello";
2 (function(){
3   var v; //declaration hoisting
4   console.log(v);
5   v = "world";
6 })();

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

1 (function(){
2   var a = "1";
3   var f = function(){};
4   var b = "2";
5   var c = "3";
6 })();

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

1 (function(){
2   var a,f,b,c;
3   a = "1";
4   f = function(){};
5   b = "2";
6   c = "3";
7 })();

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

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

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

  var f1 = function(){};
  function f2(){}
})();

上面代码中函数声明f2被提升,所以在前面调用f2是没问题的。虽然变量f1也被提升,但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有声明是被提升的。

 

原文地址:https://www.cnblogs.com/jiayuexuan/p/9263372.html

时间: 2024-11-07 09:59:56

深入理解JS中的变量及变量作用域的相关文章

[js]js的惰性声明, js中声明过的变量(预解释),后在不会重新声明了

js的惰性声明, js中声明过的变量(预解释),后在不会重新声明了 fn(); // 声明+定义 js中声明过一次的变量,之后在不会重新声明了 function fn() { console.log("ok") } fn(); //ok fn = 22; //赋值是允许的 fn(); // Uncaught TypeError: fn is not a function function fn() { console.log("ok !!!");} fn(); //

深入探究js中的隐式变量声明

前两天遇到的问题,经过很多网友的深刻讨论,终于有一个相对可以解释的通的逻辑了,然后我仔细研究了一下相关的点,顺带研究了一下js中的隐式变量. 以下文章中提到的隐式变量都是指没有用var,let,const等关键字定义的变量. 以下文章中提到的var变量都是指用var声明定义的变量. 一遇到隐式变量,我们去百度一下,都会看见这样一句话,隐式变量是全局变量,在函数中用隐式变量也是全局变量,但是在函数中用var变量是局部变量,那我们来具体看下隐式变量到底与var变量有什么区别,下面我们来通过一些代码来

理解JS中的call、apply、bind方法

理解JS中的call.apply.bind方法(*****************************************************************) 在JavaScript中,call.apply和bind是Function对象自带的三个方法,这三个方法的主要作用是改变函数中的this指向. call.apply.bind方法的共同点和区别:apply . call .bind 三者都是用来改变函数的this对象的指向的:apply . call .bind 三者

理解js中的作用域以及初探闭包

前言 对于js中的闭包,无论是老司机还是小白,我想,见得不能再多了,然而有时三言两语却很难说得明白,反正在我初学时是这样的,脑子里虽有概念,但是却道不出个所以然来,在面试中经常会被用来吊自己的胃口,考察基础,虽然网上自己也看过不少相关闭包的文章,帖子,但貌似这玩意,越看越复杂,满满逼格高,生涉难懂的专业词汇常常把自己带到沟里去了,越看越迷糊,其实终归结底,用杨绛先生的一句话就是:"你的问题在于代码写得太少,书读得不够多",其实在我看来前者是主要的,是后者的检验, 自知目标搬砖20年(还

深入理解JS中的变量作用域

在JS当中一个变量的作用域(scope)是程序中定义这个变量的区域.变量分为两类:全局(global)的和局部的.其中全局变量的作用域是全局性的,即在JavaScript代码中,它处处都有定义.而在函数之内声明的变量,就只在函数体内部有定义.它们是局部变量,作用域是局部性的.函数的参数也是局部变量,它们只在函数体内部有定义. 我们可以借助JavaScript的作用域链(scope chain)更好地了解变量的作用域.每个JavaScript执行环境都有一个和它关联在一起的作用域链.这个作用域链是

JS中函数名与变量名冲突

在JS中如果函数名与变量名冲突,JS是怎么执行的... function a(){ console.log(12); } a() var a = 10; console.log(a); JS会先把变量的声明放在最前面,然后将定义式函数放在变量声明的后面,后面赋值语句按原来的顺序I依次执行. 因此上面的代码等价于 var a; function a(){ console.log(12); } a(); a = 10; console.log(a); 因此结果是12   10.

前端开发入门到实战:HTML标签和JS中设置CSS3 var变量

一.HTML标签中设置CSS变量 如下: <div style="--color: #cd0000;"> <img src="mm.jpg" style="border: 10px solid var(--color);"> </div> 直接正常CSS语句一样在style属性中设置即可. 效果如下截图: 二.JS中设置CSS变量 如下,HTML示意: <div id="box">

web前端入门到实战:HTML标签和JS中设置CSS3 var变量

一.HTML标签中设置CSS变量 如下: <div style="--color: #cd0000;"> <img src="mm.jpg" style="border: 10px solid var(--color);"> </div> 直接正常CSS语句一样在style属性中设置即可. 效果如下截图: 二.JS中设置CSS变量 如下,HTML示意: <div id="box">

转:彻底理解js中this的指向,不必硬背

转:http://www.cnblogs.com/pssp/p/5216085.html 首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然网上大部分的文章都是这样说的,虽然在很多情况下那样去理解不会出什么问题,但是实际上那样理解是不准确的,所以在你理解this的时候会有种琢磨不透的感觉),那么接下来我会深入的探讨这个问题. 为什么要学习this?