js学习笔记基础分享--作用域和预解析

作用域和预解析

1.js作用域:变量在某个范围内起作用和效果(目的:提高程序的可靠性和减少命名冲突)

 

2.分类:全局作用域、局部作用域

2.1.全局作用域:整个script标签或者一个单独js文件

2.2.局部作用域:函数内部就是局部作用域,只在函数内部起作用

 

3.变量分类:全局变量、局部变量

3.1根据作用域的不同,变量可分为两种:全局变量、局部变量

3.2全局变量:在全局作用域下的变量。

3.3局部变量:在局部作用域下的变量。

注意:

如果在函数内部没被声明直接被赋值的变量也是全局变量(不建议使用)

函数的形参也可看做局部变量

 

4.区别:

(1)全局变量:在任何一个地方都能使用,只有浏览器关闭时才会销毁,比较占内存

(2)局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节约空间。

5.js块级作用域:

5.1.{}---if{}、for{}

5.2.//在Java中,块级作用域定义的变量不能在外面调用

        if(x){

            int num = 10;

        }

        //此时在外面调用会报错

但是现阶段js没块级作用域可以用console.log(num)调用

 

6.作用域链:

内部函数访问外部函数的变量,采取链式查找的方式来决定取哪个值。

(如果多层函数嵌套,内部函数访问上一级外部函数的变量时,如果有该变量则调用,如果无则往上一级匹配,直到匹配成功。也就是就近原则)

案例:

        var num = 10; //后匹配

        function fn() {
            var num = 20; //先匹配

            function fun() {
                console.log(num); //输出20
            }
            fun();
        }
        fn();

练习1:看看这段代码输出为几多?

        function f1() {
            var num = 123;

            function f2() {
                console.log(num);//123,就近原则
            }
            f2();
        }
        var num = 456;
        f1();

 

预解析

1、抛出问题:

//预解析
        //问1:
        console.log(num);
        var num = 10; //undefined
        //问2:
        fn(); //11
        function fn() {
            console.log(11);
        }
        //fn()放自定义函数前后都行
        //问3:
        fun();

        var fun = function () {
            console.log(22);
        }// fun is not a function

2、分析:

2-1、js引擎运行js分两步:预解析和代码执行

(1)预解析:js引擎会把js里面的所有var 还有function提升至当前作用域的最前面。

(2)代码执行:代码顺序从上往下执行

2-2、预解析:变量预解析(变量提升)、函数预解析(函数提升)

(1)变量提升:把所有变量声明提升至当前作用域最前面,不提升赋值操作

//问1:
        console.log(num);
        var num = 10; //undefined

        //相当于执行:
        var num;
        console.log(num);
        num = 10;
//问3:
        fun();

        var fun = function () {
            console.log(22);
        }// fun is not a function

        //相当于执行:
        var fun;
        fun();
        fun = function(){
            console.log(22);
        }

注意:因此函数表达式的调用必须写在函数表达式的下面

(2)函数提升:把所有函数声明提升至当前作用域最前面,不调用函数

问2:所以fn()放函数前后都行·

4,案例:

(1)案例1:

//案例1:
        var num = 10;
        fun();

        function fun() {
            console.log(num);
            var num = 20;
        }//undefined
        //相当于:
        var num;//变量提升
        function fun() {//函数提升
            var num;//函数内变量提升
            console.log(num);//就近原则,num声明未被赋值则输出undefined
            num = 20;
        }
        num = 10;
        fun();

(2)案例2:

//案例2:
        var num = 10;

        function fn() {
            console.log(num); //undefined
            var num = 20;
            console.log(num); //20
        }
        fn();
        //相当于:
        var num;

        function fn() {
            var num
            console.log(num); //undefined
            num = 20;
            console.log(num); //20
        }
        num = 10;
        fn();

(3)案例3:

//案例3:
        var a = 18;
        f1();

        function f1() {
            var b = 9;
            console.log(a); //undefined
            console.log(b); //9
            var a = "123";
        }
        //相当于:
        var a;

        function f1() {
            var a;
            var b;
            b = 9;
            console.log(a); //undefined
            console.log(b); //9
            a = "123";
        }
        a = 18;
        f1();

(4)案例4:

//案例4:
        f1();
        console.log(c);//9
        console.log(b);//9
        console.log(a);//a is not defined

        function f1() {
            var a = b = c = 9;
            console.log(a);//9
            console.log(b);//9
            console.log(c);//9
        }
        //相当于:
        function f1() {
            var a;//局部变量
            a = b = c = 9;
            //相当于 var a=9; b=9;c=9;b和c直接赋值并未声明,当全局变量看
            //若要集体声明则为 var a=9,b=9,c=9;
            console.log(a);//9
            console.log(b);//9
            console.log(c);//9
        }
        f1();
        console.log(c);//9
        console.log(b);//9
        console.log(a);//a is not defined

补充:

有关arguments的使用

//arguments的使用

        function fn() {

            console.log(arguments); //里面存储了所有传递过来的实参

            console.log(arguments.length);

        }

        fn(1, 2, 3);

        //arguments是伪数组,并不是真正意义上的数组

        //1.具有数组的length属性

        //2.按照索引的方式进行存储

        //3.他没有真正数组的一些方法pop()、push()等等

 

        //Arguments { 0: 1, 1: 2, 2: 3, … }

        //3

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值