JavaScript基础--作用域详解

目录

定义        

全局作用域

局部作用域

函数作用域

块级作用域

作用域链 

定义

查找方式


定义        

        作用域是在运行代码中某些特定部分中变量、函数、对象的可访问性。通俗点讲,可以把作用域理解为一个独立盒子,隔离变量,让变量不会外泄和暴露出去,所以不同作用域下同名变量不会发生冲突。

        ES6之前JavaScript没有块级作用域,只有全局作用域和函数作用域(ES6提供块级作用域,可通过新增命令letconst体现)

全局作用域

        代码中任何地方都能访问到的对象拥有全局作用域,一般来说如下几种情形拥有全局作用域:

        1.函数外部定义的变量

        2.函数内未定义直接赋值的变量

        3.所有window对象的属性

var a="最外层变量";             //最外层变量
function fun(){                //最外层函数
    var b="内层变量";          //定义内层变量
    c="未定义直接赋值的变量";    //"未定义直接赋值的变量"
}
fun();  //调用函数
console.log("a=",a);   //a= 最外层变量
console.log("c=",c);   //c= 未定义直接赋值的变量

        上述全局变量一直占用内存,直到浏览器页面关闭才会释放 

局部作用域

        与全局作用域相反,一般只能在固定代码片段内访问,常见于函数作用域中

函数作用域

        函数作用域内,对外封闭,从外层无法直接访问函数内部作用域,如需访问需要通过return或者利用闭包函数来实现

var a="最外层变量";             //最外层变量
function fun(){                //最外层函数
    var b="内层变量";          //定义内层变量
    c="未定义直接赋值的变量";    //"未定义直接赋值的变量"
}
fun();  //调用函数
console.log(b);  //报错 ReferenceError: b is not defined

块级作用域

        ES6新增letconst命令,可用于创建块级作用域变量,使用let命令声明的变量指再let命令所在代码块内有效(let声明语法与var语法一致,可以使用let代替var进行变量声明,但会将变量作用域限制在当前代码块中),ES6中新增的块级作用域用“{}”表示。

//用let声明变量,变量不会提升到代码块顶部
console,let(a);  //ReferenceError: let is not defined
let a=2;

//用let声明变量,不允许外部访问块级作用域内部变量
for(let i=0;i<10;i++){
    console.log(i);
}
console.log(i); //ReferenceError: i is not defined

        ES6中letconst还有一个特点:不允许反复声明 

//var可以反复声明进行覆盖
function testVar(){
    var a=1;
    var a=2;
    console.log(a);  //2
}
testVar();

//let、const不允许反复声明
function testLet(){
    let a=1;
    let a=2;
    console.log(a); //SyntaxError: Identifier 'a' has already been declared
}
testLet();
function testConst(){
    const a=1;  //改成var a=1或者let=1也是同样的效果,相同变量不能反复声明
    const a=2;
    console.log(a); //SyntaxError: Identifier 'a' has already been declared
}
testConst();

作用域链 

定义

        JavaScript上每个函数执行时,会在自己创建的活动对象上搜寻对应属性值,若没找到则往父函数的活动对象上找,仍未找到则再上一层,直至找到window全局作用域(无论是否找到,停止查找过程),这一过程可以看作是一条链,也称作用域链。

查找方式

        当我们需要使用声明的变量时,js会从所在的域一层一层向外层域查找,如果找到了就进行使用,不再进行继续查找

var value='1';
function test(){
    var value='2';
    console.log(value);       //2
    function innertest(){
        var value='3';
        console.log(value);   //3
    }
    return innertest();
}
test();
console.log(value);           //1

        层级关系如下所示:

         注意:查找变量时,要去创建这个函数的作用域中去取值,而不是调用

var a=2;
function test(){
    var b=5;
    function fun(){
        console.log(a+b);  //7
    }
    return fun;
}
var m=test();  //test()返回fun函数赋值给m
var b=10;
m();           //执行m()-->调用fun函数

        如同上例, test()返回fun函数赋值给m,执行m()调用fun函数,fun函数的变量回到其创建的作用域中去寻找,向上在test作用域中找到变量b=5,再继续向上找到全局作用域中变量a=2,故得出a+b=7,与之后在全局作用域声明的b变量无关。分析图如下所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值