javascript 变量 作用域-JavaScript 范围

作用域表示当前执行上下文,值和表达式在该上下文中可见并且可以访问。 范围决定了块代码中的可见性。

Node.js的作用域可以分为全局作用域、局部作用域和块级作用域。 在javascript中,通常存在全局范围的中学情况。

作用域存在的意义:变量隔离,不同作用域同名变量不会冲突

1. 全球范围

1、window对象的属性和方法

console.log(window.alert);

如图所示,window对象的所有属性都具有全局作用域。 之所以可以在JavaScript中的任何地方使用alert('xxxx'),是因为它被定义为window对象上的函数并且具有全局作用域。

2.最内层定义的变量、函数和对象


       c=3 //外层变量
       //最外层函数
       function fun1(){
           //内层变量
           a=1;
           a=2;
               //内层函数
              function fun2(){
                  b=2;
              }
       }
  
  console.log(c);     //3
  console.log(a);     // not definded
   console.log(fun1)  //function fun1()
   console.log(fun2) //fun2 is not defined

变量 a 和函数 fun1 具有全局作用域,可以在任何地方访问。 但是,变量 b 和 fun2 未在全局范围内定义,并且难以在全局范围内访问。

3.所有没有定义直接参数的变量都被手动声明为具有全局作用域

  function  fun(){
      a=2;
      var b=2;
  }
  fun()//首先的执行一下这个函数不然不知道里面是啥
  
console.log(a)          // 2
console.log(b)          // b is  not defined

b var 被定义并且有形参,但是变量 a 只是函数中的直接形参并且没有定义,那么变量 a 会被手动附加到 window 对象上并且具有全局作用域。

ps:常量和变量都是变量javascript 变量 作用域,但是常量是赋值后就不能改变的变量javascript 变量 作用域,而普通变量可以对形参进行操作(有人可能会奇怪a,明明是常量,(^哦^)/~)

2. 本地范围

局部作用域相当于函数作用域,指的是函数内部的空间,函数内部的变量,外部难以访问的地方

function doSomething(){
    var blogName="xx";
    function innerSay(){
        alert(blogName);
    }
    innerSay();
}
alert(blogName); //脚本错误
innerSay(); //脚本错

作用域是分层的,内部作用域可以访问内部作用域中的变量,但反之则不行。

3. 块级作用域

ES5只有全局作用域而没有函数作用域,也没有块级作用域,这带来了很多不合理的场景。

在第一种情况下,内部变量可能会覆盖内部变量:


var tmp = new Date();
 
function f(){
  console.log(tmp);
  if(false){
    var tmp = "hello";
  }
}
 
f(); // undefined

上面的代码中,函数f执行后,输出结果是未定义的。 原因是变量增大,导致外层tmp变量覆盖了内层tmp变量。

在第二种情况下,用于技术的循环变量泄漏到全局变量中:

var s = "hello";
for(var i=0;i<s.length;i++){
  console.log(s[i]);
}
console.log(i); // 5

上面的代码中,变量i只是用来控制循环,但是循环结束后,它并没有消失,而是泄漏到了一个全局变量中。

javascript 变量 作用域-JavaScript 范围

事实上,正是es6和let的出现,让JavaScript有了块级作用域。

var 没有块作用域


function fun(){
    var n =10
    if(1==true){
       var n=5   
    }
    console.log(n)  //5
}
fun();

let 具有块作用域

//块级作用域
function fun(){
    let n =10
    if(1==true){
       let n=5   
    }
    console.log(n)  //10
}
fun();

var 可以在同一作用域内重复声明


function fun(){
    var n =10
    if(1==true){
       var n=5   
       var n=9//var允许重复声明
    }
    console.log(n)  //9
}
fun();

let 不能在同一范围内重复声明

//块级作用域
function fun(){
    let n =10
    if(1==true){
       let n=5   //let不允许重复声明
       let n=9
    }
    console.log(n)  // 脚本报错
}
fun();

作用域链

在函数的内部作用域中搜索变量时,如果没有找到,则会在其父作用域中搜索。 如果在父作用域中没有找到,就会逐层查找,直到找到全局作用域。 如果未找到范围,则搜索结束并且变量被视为未定义。 这种作用域的层层嵌套关系就是作用域链。

案件:

 let a =1;
      function func1(){
          let b=2;
          function func2(){
              let c=3;
              console.log(a);   //输出全局变量a=1,根据作用域链查找
          }
          func2();
      }
       func1();

附面试题:

下面的代码中: typeof a 和 typeof b 的值分别是多少?

看代码:

 function foo(){
            let a=b=0; 
            a++;
           // return a;
            console.log(a)
        }
        foo();
          console.log( typeof a)     undefined
      console.log( typeof b)        number
        //a????     b???  

让我们仔细看看第 2 行:leta=b=0。 这句话确实声明了一个局部变量a。 但是,它确实声明了一个全局变量 b。

javascript 变量 作用域-JavaScript 范围

在 foo() 作用域或全局作用域中声明的变量 b 没有直接形式参数。 因此,JavaScript 将表达式 b=0 解释为 window.b=0。

b 是一个恰好被创建的全局变量。

在浏览器中,上面的代码片段相当于:

函数foo(){

leta;window.b=0;a=window.b;a++;

返回a;

foo();

typeofa;//=>'未定义'

typeofwindow.b;//=>'数字'

typeofa 是“未定义”。 变量 a 仅在 foo() 范围内声明,在外部范围内不可用。

typeofb 等于“数字”。 b 是一个值为 0 的全局变量。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 javascript javascript 变量 作用域-JavaScript 范围 https://www.wkzy.net/game/190156.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务