JS基础(3) 数组,函数,定义域,JS预解析

本文介绍了JavaScript中的数组创建方式,包括new创建和数组字面量,详细讲解了遍历方法。接着深入探讨了函数的声明方式,如函数表达式和闭包,并解释了return、arguments对象和作用域的概念。最后,阐述了JavaScript的预解析机制,包括变量和函数提升的规则。
摘要由CSDN通过智能技术生成

数组

JS两种创建数组的方式

利用new 创建数组    

 //使用new
        let arr = new Array();//创建了一个空数组
        arr = [1,2,3,4];
        console.log(arr);

利用数组字面量创建数组js    

 //使用字面量(常用)
        let arr2 = [];//创建了一个空数组
        arr2 = [1,2,'warm',true];
        console.log(arr2[2]);

遍历

 //遍历
        let arr3=['胡歌','沈腾','彭于晏']
        console.log('我喜欢的明星有:');
        for(let i=0 ; i<arr3.length ; i++){
            console.log(arr3[i]);
        }

函数

声明方式1:

function 函数名(形参列表){

函数体

return 返回值;

}

声明方式2:函数表达式(匿名函数)

函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而函数表达式里面存的是函数,函数表达式也可以进行传递参数。

let 变量名 = function(){

console.log('这是函数表达式,')

};

声明方式3

let f3 = (a, b) => { return a + b };

闭包函数

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

案例:查看你的生肖星座和你一共活了多少天

function Show(year, month, day) {
    function Constellation() {
        let constellation = ['摩羯座', '水瓶座', '双鱼座', '白羊座', '金牛座', '双子座', '巨蟹座',
            '狮子座', '处女座', '天枰座', '天蝎座', '射手座', '摩羯座'
        ];
        let time = [19, 18, 20, 19, 20, 21, 22, 22, 22, 23, 22, 21];
        let uConstellation = (day <= time[month - 1]) ? (constellation[month - 1]) : (constellation[month]);
        console.log(`您的星座是:${uConstellation}`);
    }

    function Showxz() {
        let year2 = year % 12;
        let shengXiao = ['猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊'];
        if (year2 >= 0) {
            console.log(`您的生肖是:${shengXiao[year2]}`);
        }
    }

    function UDay() {
        // let birthday = new Date(year, month - 1, day);//数字型 数字型date的月份是从0开始计算
        let birthday = new Date(year + '/' + month + '/' + day); //字符串型
        let today = new Date();
        let time = parseInt((today.getTime() - birthday.getTime()) / (1000 * 3600 * 24));
        console.log("从出生到今天活了" + time + "天 ");
    }
    return {
        showConstellation: Constellation(),
        showXz: Showxz(),
        showDays: UDay()
    }
}
let show = Show(2002, 1, 5);
show.showConstellation;
show.showXz;
show.showDays;

return

1.除了返回值以为还有终止函数的作用

function getSun(num1,num2){
    return num1+num2;
    alert('这里面的代码不会被执行了')
}

2.return只能返回一个值,如果没有return则返回undefined

break,continue,return的区别

break:结束当前循环体

continue:跳出本次循环,继续执行下次循环

return:不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前函数体内的代码。

arguments

当我们不确定有多少个参数传递的时候,可以用arguments来获取,在JavaScript中,arguments实际上它是当前函数的一个内资对象,所有函数的内置了一个arguments对象,arguments对象中存储了传递的所以实参。

function fn(){
    conselo.log(arguments);//拟数组对象
}
fn(1,2,3,4);

伪数组形式

arguments展示形式时一个伪数组形式,因此可以遍历,伪数组具有以下特点:

1.具有length属性

2.按索引方式存储

3.不具有数组的push,pop等方法

作用域

  1. JavaScript作用域:就是代码名字(变量)在某个范围内起作用和效果,目的是为了提高程序的可靠性更重要的是减少命名冲突。

  2. JS的作用域(es6)之前:全局作用域 局部作用域。

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

  4. 局部作用域(函数作用域) 在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用。

全局变量

  1. 全局变量:在全局作用域下的变量,在全局下都可以使用

  2. 特殊情况下 在函数内不适应var声明的变量也是全局变量(不建议使用)

局部变量

  1. 在局部作用域下的变量,后者在函数内部的变量就是,局部变量

js中没有块级作业域,js的作用域:全局作用域,局部作用域,现阶段我们js没有块级作用域,

我们js也是在es6的时候新增的块级作用域

作用域链

  1. 只要是1代码,就至少有一个作用域

  2. 写在函数内部的局部作用域

  3. 如果函数中还要函数,那么在这个作用域中就又可以诞生一个作用域

  4. 内部函数可以访问外部函数变量这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链,一级以及往上找 就近原则。

    <script>
        //作用域链 :内部函数访问外部函数 一级以及往上找 就近原则
        let num = 10;
        function fn(){
            let num = 20;
            function fun(){//内部函数
                console.log(num);
            }
            fun();//需要一层一层调用
        }
        fn();
    </script>

预解析

js引擎运行Js分为两步:预解析 和 代码执行

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

  2. 执行代码:按照代码书写的顺序从上往下执行

预解析分为 变量预解析(变量提升)和函数预解析(函数提升)。

  1. 变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作。

  2. 函数提升:把所有的函数声明提升到当前作用域的最前面。

<script>
        //1. 变量提升:就是把所有的变量声明提升到当前的作用域最前面,不提升赋值操作。
        //2. 函数提升:把所有的函数声明提升到当前作用域的最前面。
​
​
        //这两行代码相当于---变量提升
        //1. var num;   --变量声明提升到当前的作用域最前面
        //2. console.log(num);
        //3. num = 10;
        //相当于上面三行代码,这就是js中的预解析
         console.log(num);//undefined
         var num = 10;//let num的话前面会输出Cannot access 'num' before initialization
​
​
​
        fn();//可以输出11 不会报错
        function fn(){
            console.log(11);
        }
        //上面代码相当于---函数提升
        //function fn(){       ----函数声明提升到当前作用域的最前面
        //    console.log(11);
        //}
        //fn();
​
​
​
        
        fun();//fun is not a function 所以说函数表达式跟变量是一个定义是一个概念
        var fun = function(){
            console.log(22);
        }
        //上面代码相当于这几行代码---变量提升
        //var fun;
        //fun();
        //fun = function(){      -因为是变量提升 所以赋值操作无法放在前面
        //    console.log(22);
        //}
    </script>
 

预解析案例

案例1

 //案例1  报错这里是因为let要先定义才能使用所以直接走这一步后面就没得走了 Cannot access 'num' before initialization
        // let num = 10;
        // fun();
        // function fun(){
        //     console.log(num);
        //     let num = 20;
        // }
        //let num;
        // function fun(){
        //     let num ;//let标识符无法这样走 因为let不允许再次定义相同的标识符
        //     console.log(num);
        //     num = 20; 
        // }
        // num = 10;
        // fun();

        var倒是可以直接使用
        var num = 10;
        fun();
        function fun(){
            console.log(num);//输出undefined
            var num = 20;
        }
        //相当于执行了一下代码
        //var num;
        //function fun(){
            //除了外面全局变量的变量提升外 函数内部还要一次变量提升
            //var num ;
            //console.log(num);
            //num = 20; 
        //}
        //num = 10;
        //fun();

案例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);
        //     num = 10;
        //     console.log(num);
        // }
        // num = 10;
        // fn();

案例3

//案例3
        var a = 18;
        f1();
        function f1(){
            var b = 9;
            console.log(a);
            console.log(b);
            var a = '123';
        }
        //相当于
        // var a;
        // function f1(){
        //     var b;
        //     var a;
        //     b = 9;
        //     console.log(a);//undefined
        //     console.log(b);//9
        //     a = '123';
        // }
        // a = 18;
        // f1();

案例4:面试题

 // //案例4
        f1();
        console.log(c);//9
        console.log(b);//9
        console.log(a1);//报错a1 is not defined


        function f1(){
            var a1 = b = c =9;
            //上面这行代码相当于 var a = 9;b = 9; c = 9;也就是说 b和没有直接赋值 没有var声明 属于全局变量(看作全局变量)
            //我们想要的集体声明应该是这样的var(let) a = 9,b = 9,c = 9;
            console.log(a1);//9
            console.log(b);//9
            console.log(c);//9
        }
        //相当于
        // function f1(){
        //     var a;
        //     a = b = 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);//undefined

      /*  
        我们继续滤清概念再看 全局变量
        console.log(c);//c is not defined
        console.log(b);
        console.log(a);
        f1();刚刚之前哪里必须先调用f1()吧a,全局变量b,全局变量c创建出来
        function f1(){
            var a = b = c =9;
            //上面这行代码相当于 var a = 9;b = 9; c = 9;也就是说 b和没有直接赋值 没有var声明 属于全局变量(看作全局变量)
            console.log(a);
            console.log(b);
            console.log(c);
        }
    */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值