小米技术社区
小米技术社区管理员 关于小米

27岁,山西运城人,职业电商经理人,前端开发工作者,从事过网站建设、网络推广、SEO、SEM、信息流推广、二类电商、网络运维、软件开发,等相关电商工作,经验较为丰富,小米技术社区致力于为广大从事Web前端开发的人员提供一些力所能及的引导和帮助 ...[更多]

E-mail:mzze@163.com

Q Q:32362389

W X:xiaomi168527

小米技术社区大牛王飞 关于王飞

27岁,山西运城人,职业电商经理人,网络工程师兼运维,从事过运营商网络建设,企业网络建设、优化。数据中心网络维护等通过,经验丰富,座右铭:当自己休息的时候,别忘了别人还在奔跑。 ...[更多]

E-mail:wf_live@126.com

Q Q:3940019

微博:王小贱ss

小米技术社区设计小艳 关于小艳

大于花一样的年龄,河南郑州是我家,2010年在北京接触团购网,2011年进入天猫淘宝一待就是四年,如今已经将设计走向国际化(ps:误打误撞开始进入阿里巴巴国际站的设计,嘿嘿)五年电商设计,丰富经验,从事过天猫淘宝阿里各项设计,店铺运营,产品拍摄;我将我的经历与您分享是我的快乐!座右铭:越努力越幸运! ...[更多]

E-mail:97157726@qq.com

Q Q:97157726

标签云
精品推荐
  • 什么是闭包?js闭包的2个最大用途以及注意事项

    什么是闭包?js闭包的2个最大用途以及注意事项

    各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。简单的说,闭包就是能够读取其他函数内部变量的函数。由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因……
    134人已经看过了
您的位置:首页 > 前端开发 > Javascript > 原生JS

JavaScript的作用域以及作用域链,全局变量和局部变量

分类: 原生JS45个赞

我们知道函数将js运行环境,分为函数内部和函数外部两部分

注意:函数内部使用var声明的变量,和函数外部的变量,互不影响


局部作用域和全局作用域概念:

局部作用域(函数作用域)--指的是函数内部的环境

全局作用域--指的是整个运行环境

词法作用域--全局作用域、局部作用域; 统称为 词法作用域


块级作用域--EC6新增,块级声明用于声明在指定块的作用域之外无法访问的变量。块级作用域存在于:1)函数内部  2)块中

(1)let声明

let可以把变量的作用域限制在当前代码块中,不会被提升,通常放在封闭代码块的顶部。

(2)禁止重声明

let不能声明一个已经有标识的变量,会抛出错误

(3)const声明

const声明的是常量,其值不但被设定之后不可更改


EC6中const与let

共同点:

1)都是块级标识符

2)只在当前代码块内有效

3)常量也不会被提升至作用域顶部

不同点:const是常量,不能再次赋值,而let是可以的

let和const与var的另外一个区别是他们在全局作用域中的行为:


var 被用于全局作用域时,那么就会创建一个新的全局变量作为全局对象的属性。

let和const则不会创建全局对象的属性。

let还有一个很大的作用,曾经让我们头疼的经典问题,for循环i变量丢失的问题,经常输出最后一个值得那个问题,终于用let解决,简化了循环过程,不再使用立即调用函数表达式,就可以解决了!

局部变量和全局变量概念:

局部变量--局部作用域中var声明的变量,叫做局部变量,只能在函数内部(局部作用域)中使用

全局变量--全局作用域的变量叫全局变量,在任何地方都可以使用


注意:函数里面声明了变量,则使用自己的;如果没有声明变量,则使用全局变量,即局部作用域可以使用全局作用域的变量(函数内部可以使用函数外部的变量)


案例1:

var num = 100;
(function(){
 var num = 200;
 console.log(num);
})();
console.log(num);
//结果 200 100


案例2:

var num = 100;
function f1(){
 // var num = 200;
 console.log(num);
}
f1();
console.log(num);
//结果100 100


变量的提升效果(不推荐使用)

概念:变量的提升,是将变量的声明,提升到当前作用域的最前面

特点:变量先使用后声明,变量的声明会提前,赋值不会提前

案例1: 全局环境下的,变量的提升效果


console.log(num);
var num = 100;
//结果 undefined
//它真正执行过程如下:
var num; //变量的声明 提前了
console.log(num);
num = 100;


案例2: 在函数中 变量也有提升效果


function fn(){
 console.log(num); // 结果也是undefined
 var num = 200;
//相当于
 // var num;
 // console.log(num);
 // num = 200;
}
fn();
// 函数中的变量提升,只是提升到函数作用域/局部作用域的最前面,而不会提升到全局
console.log(num); //报错


函数预加载(同样不推荐使用)

函数预加载特点:

(1)函数可以先调用,后声明,函数也有提升效果

(2)函数预加载效果,只是针对 函数funtion 关键字的声明方式有效

(3)表达式方式声明函数,没有函数预加载效果


案例1:函数预加载--函数funtion关键词声明


fn();
function fn(){
 console.log(300);
}

案例2:表达式方式声明函数,没有函数预加载效果

console.log(f1);
f1();
var f1 = function(){
 console.log(400);
}
//真正执行顺序如下
var f1;
f1(); //报错 f1不是一个函数
f1 = function(){
 console.log(400);
}


作用域链(js三大难点之一)

    案例1  函数内部可以使用函数外部的变量

    var num = 100;
    function f1(){
     console.log(num);
    }
    f1(); //结果100



    案例2 函数外部不可以使用函数内部的变量

    function f2(){
     var num = 100;
    }
    f2();
    console.log(num); //报错

    

    

    案例3 函数中定义变量 没有使用var或let,相当于在函数外部声明了全局变量,在函数内部进行的赋值

    注意: 声明变量,使用var和不使用var 的区别
    var num;
    function f3(){
     num = 100;
    }
    f3();
    console.log(num); // 100

    

    

    案例4 函数内外,有同名的变量,函数内部优先使用内部自己的变量;自己没有,就向外层找

    var num = 100;
    function f1(){
     var num = 200;
     console.log(num);
    }
    f1();
    console.log(num); //结果 200 100

    案例5:函数的作用域和它在哪里调用没有关系,它的作用域在它声明的地方

f2调用没有变量a,他会去上一层找,就是1

var a = 1;
function f1(){
    var a = 2;
    
}

function f2(){
    console.log(a);
}

f1();  //结果为1

多层作用域

    var num = 100;
    function f1(){
     var num = 200;
     console.log(num);
     function f2(){
         var num = 300;
         console.log(num);
     }
     f2();
    }
    f1();
    console.log(num);//结果200 300 100


作用域链概念:

最内层作用域,使用变量,自己没有,则先向外找一层,如果还是没有,就一直向外找。直到找到一个为止。这种查找变量的值 的链式方式(链式结构)(从内向外), 叫做作用域链。

    var num = 100;
    function f1(){
        var num = 200;
        console.log(num);
        function f2(){
            console.log(num);
        }
        f2();
    }
    f1();
    console.log(num);

作用域链分解图

js三个难点作用域链,原型链,闭包,2链1包

它们本身没有什么代码,只是一个概念而已,而是查找变量的方式,

作用域链:先找自己,自己没有找外面的,外面没有再找外面的外面的

以后看到这种代码,你要知道他用的是哪个值,作用域链是自己最近的那个变量


相关阅读:

js中代码的运行方式(预编译过程和执行流程)

小米技术社区

本站内容均为小米原创,转载请注明出处:小米技术社区>> JavaScript的作用域以及作用域链,全局变量和局部变量