JS基础(二)运算符、流程控制语句、数组对象、JSON对象、Date对象、Math对象、Function对象(包括JS预编译)
一 运算符
    <script>
        // 算数运算符
        // (1) 自加运算
        var x = 10;
        // x = x + 1;
        // x += 2;
        var ret = x++;   // 先赋值再计算: x += 1
        // var ret = ++x;      //先计算再赋值:    x += 1
        console.log(x);
        console.log(ret);
        // (2) 比较运算
        console.log(1 == "1"); // TRUE
        console.log(1 === "1"); // FALSE 不允许JS做任何暗转换,必须严格相等
        // (3) 逻辑运算符
        console.log(Boolean(3>2 && 2===1));
        console.log(Boolean(3>2 || 2===1));
        console.log(Boolean(!3>2));
        // (4) 短路运算
        console.log(1 && 2);
        console.log(3 || 2);
        console.log(0 && 2);
        console.log(0 || 5);
        // (5) 三元运算符
        var age =2;
        var ret = age>=18?"成年":"未成年";
        console.log(ret)
    </script>
二 流程控制语句
python中是用缩进,
if 条件:
缩进的内容
JS中不是,像Java。
    <script>
        /*
        // if分支分支
        //  双分支语句
        if(表达式){
        }else{
        }
        // 多分支语句
        if(表达式){
        }else if(表达式){
        }else if(表达式){
        }else if(表达式){
        }else{
        }
        // switch分支语句
        */
        var user = "root";
        var pwd = "12";
        if(user === "root" && pwd === "123"){
            console.log("登录成功!")
        }else {
            console.log("登录失败!")
        }
        var score  = 86;
        if (score>90){
            console.log("成绩优秀!")
        }else if(score>80){
            console.log("成绩良好!")
        }else if(score>60){
            console.log("成绩及格!")
        }else{
            console.log("成绩不及格!")
        }
       // switch语句
        var weekend = 3;
        switch (weekend) {
            case 1:console.log("星期一");break;
            case 2:console.log("星期二");break;
            case 3:console.log("星期三");break;
            case 4:console.log("星期四");break;
            case 5:console.log("星期五");break;
            case 6:console.log("星期六");break;
            case 0:console.log("星期日");break;
            default:console.log("无效数字!");break;
        }
    </script>
三 数组对象
    <script>
        // 数组的声明两种方式
        var arr01 = [12,"hello",true];
        console.log(arr01,typeof arr01);  // "object"
        var arr02 = new Array(12,"hello",true);
        console.log(arr01,typeof arr02);
        console.log(arr01.length);
        // 数组的方法
        // var arr = [1,2,3,4,5];
        // 1 插入和删除
        // arr.push("a");
        // arr.push([111,222]);
        // console.log(arr);
        // var ret = arr.pop();
        // console.log(ret);
        // console.log(arr);
        // arr.unshift(100);
        // console.log(arr);
        // arr.shift();
        // console.log(arr);
        // 2 反转和排序
        // var arr02 = [1,4,3,6,2];
        // var arr02 = [1,4,10,6,2,100];
        // arr02.reverse();
        // console.log(arr02);
        /*function sort_num(a,b){
            return a-b
        }
        arr02.sort(sort_num);
        console.log(arr02);*/
        // splice方法
        var arr = [1,2,3,4,5];
        // (1)删除多个元素
        // arr.splice(2,2);
        // console.log(arr);
        // (2) 添加多个元素
        // arr.splice(2,0,100,101,102);
        // console.log(arr);
        // (3) 替换多个元素
        // arr.splice(2,2,33,44);
        // console.log(arr);
        var arr1 = [1,2,3];
        var arr2 = [4,5,7];
        var ret = arr1.concat(arr2);
        console.log( ret );
        // join方法
        var s = "zhangsan li wangwu";
        var ret = s.split(" ");
        console.log(ret);
        var s2 = ret.join("-");
        console.log(s2);
        console.log(arr1.includes(2));
        console.log(arr1.indexOf(3));
        console.log(Array.isArray(arr1));
       // 切片操作
       arr3 = [111,222,333,444,555,666];
       console.log(arr3.slice(1,3));
       console.log(arr3.slice(1,-1));
       console.log(arr3.slice(1));
       console.log(arr3.slice());
       console.log(arr3.slice(-3,-2));
       console.log(arr3.slice(-2,-3));  // []
        // 数组循环
        for (var i=0;i<arr3.length;i++){
            // 循环体
            console.log(i,arr3[i])
        }
    </script>
四 JSON对象
JSON是JavaScript的对象表示法(JavaScript Object Notation),轻量级的数据交换格式,易于阅读和编写。
json中的成员如果是键值对,键名必须是字符串,而json中的字符串必须使用双引号圈起来。
前端项目中,一般使用json作为配置文件。
json可以让语言之间进行通信,易于数据传输。
JS序列化和反序列化:
    <script>
        var s = '{"name":"bj","age":20}'
        // 把一个json字符串解析成JS能识别的数据类型:反序列化
        var data = JSON.parse(s);
        console.log(data,typeof(data))  //{"name":"bj","age":20}  object类型
        // 把JS的数据类型转换成json字符串:序列化
        var res = {
            state:true,
            data:[123,234,456]
        };
        var res_json = JSON.stringify(res)
        console.log(typeof(res)) // object
        console.log(res_json,typeof(res_json)) // {"state":true,"data":[123,234,456]} string
    </script>
五 Date对象
六 Math对象
    <script>
        // Number对象内置方法
        // tofix(*) 保留小数位
        var num = 3.1415926
        console.log(num.toFixed(2)) //3.14
        // Math对象内置方法
        // abs()绝对值
        console.log(Math.abs(num))
        // ceil()向上取整
        console.log(Math.ceil(num))
        // floor()向下取整
        console.log(Math.floor(num))
        // max(*,*,*...)
        // min()
        // pow(x,y)  x的y次方,等于2**3
        console.log(Math.pow(2,3));
        console.log(2**3)
        //random() 生成0-1随机数
        //random()*10 生成0-10随机数
    </script>
七 Function对象
函数在程序中代表的就是一段具有功能性的代码,可以让我们的程序编程更加具有结构性和提升程序的复用性,也可以让代码变得更加灵活强大。
1. 声明函数
函数的定义方式1:  
function 函数名(参数){
      函数体;
      return 返回值;
}
功能说明:可以使用变量、常量或者表达式作为函数调用的参数,函数关键字function定义。
函数名的定义规则与标识符一致,大小写是敏感的,返回值必须用return。
函数的定义方式2:
用Funcion类直接创建函数,语法如下:
var 函数名 = new Function("参数1","参数2",...);
虽然由于字符串的关系,第二种定义形式写起来有点复杂,但有助于理解函数不过就是一种引用类型,它的行为与用Function类明确创建函数行为是相同的。
2. 函数调用
3. 函数参数
形参实参:
       function foo(x,y){
           console.log("x:",x);
           console.log("y:",y);
       }
       foo(1,2,3) // js很宽松,不会报错
       foo(1) // 不报错 y: undefined
默认参数:
比如 function stu_info(name,gender="male"){ }
arguments 参数:
       function add(){
           console.log("arguments:",arguments);
           var ret = 0 ;
           for(var i in arguments){
               ret += arguments[i];
           }
           return ret;
       }
       console.log(add(1,2,3,4)) 
4. 匿名函数
匿名函数,即没有名字的函数,在实际开发中使用的频率非常高,也是学号js的重点。
注意:使用匿名函数表达式时,函数的调用语句,必须放在函数声明语句之后。
使用普通函数,因为预编译的关系,调用语句可以放在函数声明之前。
    <script>
        // 匿名函数的调用方式1:
        var foo = function (){
            console.log("匿名函数")
        }
        foo();
        // 匿名函数的调用方式2:
        (function(){
            console.log("匿名函数")
        })();
        // 实例
        (function(x,y){
            console.log(x+y)
        })(1,2);
        // 高阶函数
        function bar(){
            return function(){
                console.log("inner函数")
            }
        }
        
    </script>
5. 函数作用域
作用域是js最重要的概念之一。要理解js作用域和作用域的工作原理。
任何程序设计语言都有作用域的概念,作用域就是变量的可访问范围,控制着变量与函数的可见性和生命周期,在js中,变量的作用域有全局作用域和局部作用域,
局部变量,在函数内部声明,它的生命周期在当前函数被调用的时候,当函数调用完毕后,内存中自动销毁当前变量;
全局变量,在函数外部声明,它的生命周期在当前文件中被声明以后就保存在内存中,直到当前文件执行完毕以后,才会在内存销毁掉。
6. JS预编译
首先一道面试题:等学完再回来看
       var num3 = 10
       function  func2(){
           console.log(num3);
           var num3 = 20
       }
       func2();
       console.log(num3);
js运行三个阶段:
- 语法分析
- 预编译
- 解释执行
语法分析就是js引擎去检查代码是否有语法错误,解释执行就是执行代码。预编译简单理解就是在内存中开辟一些空间,存放一些变量与函数。
预编译分为全局预编译和局部预编译。
- 在js脚本加载之后,会先检查是否存在低级错误;
- 在语法检查完成后,开始全局预编译;
- 在全局预编译之后,就解释一行,执行一行;
- 在执行到函数调用那一行的前一刻,会先进行函数预编译,再往下执行。
全局预编译的三个步骤:
- 创建GO对象(Global Object),即Windows对象;
- 找变量声明,将变量名作为GO属性名,值为undefined;
- 查找函数声明,作为GO属性,值赋予函数体。
局部预编译的四个步骤:
- 创建AO对象(Activation Object),执行上下文;
- 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined;
- 将实参值和形参统一;
- 在函数体里面找函数声明,值赋予函数体。
案例:
<script>
var a = 10;
console.log(a);
function foo(a) {
console.log(a);
var a = 100;
console.log(a);
function a() {
}
console.log(a);
var b = function () {
};
console.log(b);
function d() {
}
}
var c = function () {
console.log("匿名函数C");
};
console.log(c);
foo(20);
</script>
全局预编译:(一定小心c匿名函数,和标准函数声明是不一样的,不是作为函数变量,根本上是作为一个变量赋值)
        G0/window = {
            a: undefined,
            c: undefined,  // c是匿名函数,和标准函数声明是不一样的,不是作为函数变量,根本上是作为一个变量赋值
            foo: function (a) {
                console.log(a);
                var a = 123;
                console.log(a);
                function a() {
                }
                console.log(a);
                var b = function () {
                }
                console.log(b);
                function d() {
                }
            }
        }
解释执行代码(直到执行调用函数foo(20)语句):
        Go / window = {
            a: 10,
            c: function () {
                console.log("匿名函数c");
            },
            foo: function (a) {
                console.log(a);
                var a = 123;
                console.log(a);
                function a() {
                }
                console.log(a);
                var b = function () {
                }
                console.log(b);
                function d() {
                }
            }
        }
调用foo(20)之前发生的局部预编译:
// 局部预编译前两步
AO = {
    a: undefined,
    b: undefined,
}
// 局部预编译第三步
AO = {
    a: 20, //这里值是等于实参
    b: undefined,
}
// 局部预编译第四步
AO = {
    a: function a() {
    },
    b: undefined,
    d: function d() {
    },
}
最终运行的结果(有一点没懂捏):
        var a = 10;
        console.log(a); // 10
        function foo(a) {
            console.log(a);  // function c(){} ?这里有点晕
            var a = 100;
            console.log(a); //100
            function a() {  //这个是局部预编译开辟空间用的,没有做什么,所以打印的a还是100
            }
            console.log(a); // 100
            var b = function () {
            };
            console.log(b); // 空函数体 function b(){}
            function d() {
            }
        }
        var c = function () {
            console.log("匿名函数C");
        };
        console.log(c); 
        foo(20);
 
                    
                     
                    
                 
                    
                 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号