js变量作用域(解析机制)

作用域
全局作用域
局部作用域 :函数作用域

    var name = 'xm';
    function fn(argument) {
        var sex = 'male';
    }
    console.log(sex);
    fn();

console.log(sex) 这里会发生报错 sex变量是未定义的
全局变量可以在局部作用域中访问到,局部变量 在全局作用域中访问不到。

在js中没有块级作用域
{ } 如果有的话就叫做块级作用域 比如

if (true) {
        var name = 'xm';
    }
    for (var i = 0;) {

    }

如果有块级作用域 里面的变量 生也萧何 败也萧何

变量对象

    var name = 'xm';
    function fn(argument) {
        var sex = 'male';
        function fn2(argument) {
            var age = 18;
            fn2.age
        }
        fn.sex
        fn.fn2
    }
    window.name
    window.fn
    name
    fn
    console.log(window.name === name);
    console.log(window.fn === fn);
    fn
    console.log(window.person);

console.log(window.person);结果是undefined 未定义的属性

作用域链

var name = 'xm';
    function fn() {
        var name = 'xh';
        var sex = 'male';
        function fn2() {
            var name = 'xhei';
            var age = 18;
        }
    }

这里写图片描述
从最里层作用域,通过作用域链可以访问到最外层的变量,
内层变量的优先级高于外层变量的优先级。

js解析机制-预解析
预热

    var name = 'xm';
    var age = 18;
    function fn() {
        var name = 'xh';
        var age = 10;
        console.log(name);
    }
    fn();

很正常打印的结果是 xh,接着看下面
js解析过程 (预解析, 是对 var 声明的变量 和 function 函数进行预解析需要注意的是 argument 和局部变量同等对待)
预解析逐行解读代码

    var name = 'xm';
    var age = 18;
    function fn(argument) {
        console.log(name);
        var name = 'xh';
        var age = 10;
    }
    fn();

这里打印的的结果是undefined 原因

    window
        name = undefined
        age = undefined
        function fn(argument) {
            console.log(name);
            var name = 'xh';
            var age = 10;
        }
    fn
        name = undefined
        age = undefined
        argument = undefined

先预解析,window作用域下 name=undfined,age=undefined, fn,
在fn 作用域下预解析 name=undefined,age = undefined,argument= undefined
然后逐行执行代码 so 返回的结果是 undefined

解析详解 js 作用域问题1

    console.log(a);
    var a = 1 ;

返回结果 undefined

    console.log(a);
     a = 1 ;

这里会发生报错 没有var js不能正常预解析

js作用域问题2

console.log(a);
    var a = 1;
    console.log(a);
    function a() {
        console.log(2);
    }
    console.log(a);
    var a = 3;
    console.log(a);
    function a() {
        console.log(4);
    }
    console.log(a);
    a();

这里返回的结果是

function a() {
        console.log(4);
    }
 1
 1
 3
 3
 报错

分析:在预解析中 现对var 和function 进行预解析,当var声明的变量和 function声明的变量相同发生命名冲突时 ,预解析结果保留function 当function 与后面的function 命名发生冲突(名称相同) ,预解析结果保留最后一个function ,
在逐行执行过程中a()返回的结果会报错的原因是,在a()前面 执行的var a = 3 所以此时的变量a 是常用类型 3 然后会报错。

3.JS作用域问题三 (预解析是分标签进行的)

<script>
    var a = 1;
</script>
<script>
    console.log(a);
</script>

当第一个标签预解析完成和执行完成 ,然后才对第二个script进行预解析然后执行

作用域问题4 还是很有意思的

    var a =1;
    function fn() {
        console.log(a);
        var a =2;
    }
    fn();
    console.log(a);

返回的是undefined 和 1

    var a = 1;
    function fn() {
        console.log(a);
        a = 2;
    }
    fn();
    console.log(a);

结果是1 2 分析当执行到里面的 console.log(a) 此时的fu函数作用域里面 是没有局部变量a的 a=2 是全局变量,所有此时 console.log(a) 的a通过作用域链向上查找返回结果1;
全局变量中的console.log(a)返回结果是2 ;原因当执行fn()之后 此时的a全局变量的值是a 如果不执行fu() 直接打印全局变量中的 console.log(a);结果还是1 。

例子3

    var a = 1;
    function fn(a) {
        console.log(a);
        a = 2;
    }
    fn();
    console.log(a);

执行的结果是undefined和1 分析:fu(a) 中的a 是参数 在预解析中解析的结果是undefined 所以第一结果是undefined,fu 里面的a=2修改的是局部变量参数a的数值 对全局变量中的a=1 没有影响,所以全局变量中的console.log(a)结果是1

例子4

    var a = 1;
    function fn(a) {
        console.log(a);
        a = 2;
    }
    fn(a);
    console.log(a);

执行结果是1 1 分析 fn(a) 是按值传递的 fn里面的 console.log(a);
a的值是全局变量的值。a=2 是把参数的值变成2 与全局变量a=1 没有影响 全局变量中console.log(a); 结果是 1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值