js语法基础

1标识符 2-5数据类型和数据类型的转化 6算数运算符 7赋值运算符 8自增自减运算符 9关系运算符 10逻辑运算符 11逗号运算符 12三目运算符 13条件语句 14循环语句 15变量作用域 16break和continue关键字 17数组 18函数 19预解析

1.标识符的命名规则

  • 只能由字母、数字、_、$组成
  • 不能以数字开头
  • 不能使用关键字,保留字

2.数据类型

  • 基本数据类型
    Number Strinng Bolean Undefined Null (数值类型 子字符串类型 布尔类型 未定义类型 空类型)
  • Object 引用数据类型
  • 检测数据类型 typeof

3.转化为数值类型

  • string转化number
    数值的字符串,数字
    ' ' 空字符串, 0
    数字加其他的字符串,NaN
  • boolean是true1 false0
  • null转化number是0
  • undefined转化number是NAN
  • 空字符串/false/null转换之后都是0 字符串中不仅仅是数字/undefined转换之后是NaN
  • 转化的方法:Number() / +和- / ParseInt()和ParseFloat()

4.转化为字符串类型

  • Number和Boolean, 可以通过变量名.toString()
  • String(value)
  • 常亮or变量 + ' '

5.转化为布尔类型

  • string转化Boolean
    空字符串' '为false,其他为true
  • number
    0为false,NaN为false
  • undefined, null都是false
  • 空字符串/0/NaN/undefined/null 会转换成false, 其它的都是true
  • 方法:Boolean()

6.算数运算符 + - * / %

  • 和字符串相加,会拼接字符串
  • 和字符串相减,会转化number再运算
  • 任何和NaN进行运算,都是NaN
  • Bolean Undefined Null参与加减会被强制转化为number类型

7.赋值运算符

  • = += -= *= /= %=
    例如:res += 1同res = res+1

8.自增自减运算符 ++ --

  • 符号在前面,先自增再运算
  • 符号在后面,先运算再自增
       let num = 1;
        // let res = num++ + 1; // let res = num + 1; num++; 2
        let res = ++num + 1;  // num++; let res = num + 1; 3
        console.log(res); // 

9.关系运算符 > < >= <= == != === !==

  • 返回值Boolean
  • 和number比较,转化为number再判断
  • 和NaN比较,返回false
  • 都是string,比较对应的Unicode编码
  • 判断NaN,使用方法isNaN(),因为NaN == NaN或NaN === NaN结果都是false
  • 判断取值和类型 === !== 判断取值 == !=
  • 关系运算符中 > < >= <= 的优先级高于 == != === !==
  • 不能利用关系运算符来判断区间
    let res = 10 > 5 > 3; // let res = true > 3; let res = 1 > 3;

10.逻辑运算符

  • 与 &&
    一假则假
    条件A && 条件B
    A不成立,返回A(因为判断为false后,就会终止后面的运算)
  • 或 ||
    一真则真
    条件A || 条件B
    A成立,返回A(因为判断为true后,就会终止后面的运算)
  • 非!
    取反
  • &&的优先级高于||

11.逗号运算符

  • 在JavaScript中逗号运算符一般用于简化代码
    利用逗号运算符同时定义多个变量
    let a, b;
    利用逗号运算符同时给多个变量赋值
    a = 10, b = 5;
  • 逗号运算符的优先级是所有运算符中最低的
  • 逗号运算符的运算符结果就是最后一个表达式的结果
    表达式1, 表达式2, 表达式3, ....;
 let res = ((1 + 1), (2 + 2), (3 + 3));
console.log(res);//6

12.三目运算符

  • 条件表达式 ? 结果A : 结果B;
    let res = (1 > 5) ? 1 : 5;

13.条件语句

  • if
//第一种形式
        if(条件表达式){
            条件满足执行的语句;
        }

//第二种形式
        if(条件表达式){
            条件成立执行的语句;
        }else{
            条件不成立执行的语句;
        }

//第三种形式
        if(条件表达式A){
            条件A满足执行的语句;
        }else if(条件表达式B){
            条件B满足执行的语句;
        }
        ... ...
        else{
            前面所有条件都不满足执行的语句;
        }
  • switch
        switch(表达式){
            case 表达式A:
                语句A;
                break;
            case 表达式B:
                语句B;
                break;
            ... ...
            default:
                前面所有case都不匹配执行的代码;
                break;
        }
//例
        let day = 7;
        switch (day) {
            case 1:
                console.log("星期1");
                break;
            case 2:
                console.log("星期2");
                break;
            case 3:
                console.log("星期3");
                break;
            default:
                console.log("Other");
                break;
        }
  • if 和switch的选择
    几个固定的值使用switch,其他使用if

14.循环语句

  • while
        while(条件表达式){
            条件满足执行的语句;
        }
//死循环
        while (true){
            console.log("123");
        }
  • dowhile
        do{
            需要重复执行的代码;
        }while(条件表达式);
        //dowhile循环的特点: 无论条件表达式是否为真, 循环体都会被执行一次
  • for
        for(初始化表达式;条件表达式;循环后增量表达式){
            需要重复执行的代码;
        }

//例如
        for(let num = 1;num <= 10;num++){
            console.log("次数" + num);
        }


//在for循环中"初始化表达式""条件表达式""循环后增量表达式"都可以不写
         for(;;){ //for循环是可以省略条件表达式的, 默认就是真
            console.log("123");
         }

15.变量作用域

  • var 定义变量
    可以重复定义同名的变量,并且"相同作用域内"后定义的会覆盖先定义的
    可以先使用后定义(预解析)
  • let 定义变量
    "相同作用域内"不可以重复定义同名的变量
    不可以先使用后定义(不能预解析)
  • 局部作用域
    在函数{}内
  • 块级作用域
    没有和函数结合在一起{}
  • 全局变量
    省略var或let的变量
    在全局作用域中定于的变量
    在块级作用域中通过var定义的变量是全局变量
  • 局部变量
    在局部作用域定于的变量
    在块级作用域中通过let定义的变量是全局变量
  • 作用域链
    变量在作用域链查找规则,就近原则

16.break和continue关键字

  • break关键字可以用于switch语句和循环结构中
    立即结束当前的switch语句
    终止循环
  • continue关键字只能用于循环结构
    在循环结构中continue关键字的作用是跳过本次循环, 进入下一次循环
        for(let num = 1; num <= 10; num++){
            if(num === 1){
                continue;
                console.log("continue后面的代码"); // 永远执行不到
            }
            console.log("发射子弹" + num);//跳过1
        }

17.数组

  • 创建一个数组
    通过构造函数创建:let arr = new Array(size);
    字面量的方式:let arr = [ ]

  • 数组遍历
    for(let i = 0; i < arr.length; i++){
    console.log(arr[i]);
    }

  • 数组结构赋值
    一般:let [a, b, c] = [1, 3];//c是undefined
    给定默认值:let [a, b = 666, c = 888] = [1,2];//b是2
    使用扩展运算符(扩展运算符只能写在最后): let [a, ...b] = [1, 3, 5];//b[3,5]

  • 数组常用的方法

  1. 清空数组
    let arr = [1, 2, 3, 4, 5];
    // arr = [ ];
    // arr.length = 0;
    // arr.splice(0, arr.length)
  2. 将数组转化为字符串
    let arr = [1, 2, 3, 4, 5];
    //let str = arr.toString();
    // let str = arr.join('分隔符') 默认为','
  3. 拼接数组
    // let arr1 = [1, 3, 5];
    // let arr2 = [2, 4, 6];
    // let res = arr1.concat(arr2);
    // let res = [...arr1, ...arr2];
  4. 反转数组
    arr.reverse();
  5. 截取数组
    arr.slice(start,end)
    不包括end
    返回值:array 被截取的元素的数组
  6. 查找索引
    arr.indexOf(item,start);
    arr.lastIndexOf(item,start);
    返回值:number 元素的索引,没有返回-1
  7. 是否包含
    arr.includes(value);
  8. 删除,替换
    array.splice(index,howmany,item1,.....,itemX)
    改变原始数组
    返回值:array 被删除的元素的数组
  9. 在数组最后增删
    array.push(item1, item2, ..., itemX)
    改变原始数组
    数组的末尾添加一个或多个元素,并返回新的长度
    array.pop()
    改变原始数组
    删除数组的最后一个元素并返回删除的元素
    10.在数组开始增删
    array.unshift(item1,item2, ..., itemX)
    array.shift()

18.函数

  • 定义
    函数是专门用于封装代码的, 函数是一段可以随时被反复执行的代码块
  • 格式
    function 函数名称(形参列表){
    被封装的代码;
    }
//一般
        function getSum(a, b) {
            console.log(a, b);
            return a + b;
        }
//保存到变量
let getSum = function (a, b) {
            console.log(a, b);
            return a + b;
        }
  • 函数return
    return作用结束当前所在函数
    函数没有通过return明确返回值, 默认返回undefined
  • 调用函数时实参的个数和形参的个数可以不相同
  • 函数实参的默认值
//es6之前
        function getSum(a, b) {
            a = a || "1";
            b = b || "2";
            console.log(a, b);
        }
        getSum(123, "abc");
//es6之后
        function getSum(a = "1", b = getDefault()) {
            console.log(a, b);
        }
        getSum();
        // getSum(123, "abc");
        function getDefault() {
            return "2"
        }
  • 函数是引用数据类型(对象类型)
  • 函数arguments
    保存所有传递给函数的实参,例如 console.log(item1,...,itemX);
  function getSum() {
            // 注意点: 每个函数中都有一个叫做arguments的东东
            // arguments其实是一个伪数组
            console.log(arguments);
            console.log(arguments[0]);
            console.log(arguments[1]);
            console.log(arguments[2]);
}
 getSum(10, 20, 30, 40);
image
  • 函数的扩展运算符
  1. 在左边,将剩余的数据打包到一个新的数组中(解构赋值)
    只能写在最后
    let [a, ...b] = [1, 3, 5];// a = 1; b = [3, 5];
  2. 在右边,将数组中的数据解开
    let arr1 = [1, 3, 5];
    let arr2 = [2, 4, 6];
    let arr = [...arr1, ...arr2];// arr = [1, 3, 5, 2, 4, 6];
  3. 扩展运算符在函数的形参列表中的作用
    将传递给函数的所有实参打包到一个数组中
    只能写在形参列表的最后
        function getSum(...values) {
            // console.log(values);
            let sum = 0;
            for (let i = 0; i < values.length; i++){
                let num = values[i];
                sum += num;
            }
            return sum;
        }
        let res = getSum(10, 20, 30, 40);
        console.log(res);
  • 函数作为参数和返回值
//作为参数
        function a(){
            console.log('a');
        }

        function test(fn) {
            fn();
        }
        test(a);
//作为返回值
        function test() {
            // 注意点: 在其它编程语言中函数是不可以嵌套定义的,
            // 但是在JavaScript中函数是可以嵌套定义的
            let say = function () {
                console.log("hello world");
            }
            return say();
        }
        test();
  • 匿名函数
    作为其他函数的参数
    作为其他函数的返回值
    作为一个立即执行的函数
    不能够只定义不使用
        // 作为其他函数的参数
        function test(fn) { 
            fn();
        }
        test(function () {
            console.log("hello world");
        });
        // 作为其他函数的返回值
        function test() {
            return function () {
                console.log("hello lnj");
            };
        }
        let fn = test(); 
        fn();
        // 作为一个立即执行的函数
        (function () {
            console.log("hello it666");
        })();
  • 箭头函数
    格式:
    let 函数名称 = (形参列表) =>{
    需要封装的代码;
    }
    let say = () => {
    console.log("hello world");
    }
    只有一个形参, 那么()可以省略
    let say = value => {
    console.log("hello world");
    }
    只有一句代码, 那么{}也可以省略
    let say = value => console.log("hello world");
  • 递归函数
    递归函数就是在函数中自己调用自己, 我们就称之为递归函数
    递归函数在一定程度上可以实现循环的功能
    每次调用递归函数都会开辟一块新的存储空间, 所以性能不是很好
//不使用递归
        let pwd = -1;
        do{
            pwd = prompt("请输入密码");
        }while (pwd !== "123456");
        alert("密码正确");
//使用递归
        function login() {
            let pwd = prompt("请输入密码");
            if(pwd !== "123456"){
                login();
            }
            alert("密码正确");
        }
        login();
如上流程,会弹出3次 第三方的图片
js语法基础_第1张图片
直接上传的图片

19.预解析

  • 浏览器在执行JS代码的时候会分成两部分操作:
    预解析以及逐行执行代码,也就是说浏览器不会直接执行代码,
    而是加工处理之后再执行,这个加工处理的过程, 我们就称之为预解析
  • 预解析的规则
    将变量声明和函数声明提升到当前作用域最前面
    将剩余代码按照书写顺序依次放到后面
    通过let定义的变量不会被提升(不会被预解析)
    如果将函数赋值给一个var定义的变量, 那么函数不会被预解析, 只有变量会被预解析
 //var 定义变量预解析
        // 预解析之前
        console.log(num); //undefined
        var num = 123;
        // 预解析之后
        var num;
        console.log(num);
        num = 123;
        
 //函数预解析
        // ES6之前定义函数的格式
        console.log(say);
        say();
        // ES6之前的这种定义函数的格式, 是会被预解析的, 所以可以提前调用
        function say() {
            console.log("hello world");
        }
        // 预解析之后的代码
        function say() {
            console.log("hello world");
        }

//函数赋值给一个var定义的变量
        say();
        console.log(say);
        say(); // say is not a function
        // 如果将函数赋值给一个var定义的变量, 那么函数不会被预解析, 只有变量会被预解析
        var say = function() {
            console.log("hello itzb");
        }
        var say; //undefined
        say();
        say = function() {
            console.log("hello itzb");
        }
  • 预解析case
//case1
        var a = 666;
        test();
        function test() {
            var b = 777;
            console.log(a);
            console.log(b);
            console.log(c);
            var a = 888;
            let c = 999;
        }
/*
        var a;
        function test() {
           var b;
           var a;
           b = 777;
            console.log(a); // undefined
            console.log(b); // 777
            console.log(c); // 报错
            a = 888;
            let c = 999;
        }
        a = 666;
        test();
*/
//case2   
         //如果变量名称和函数名称同名, 那么函数的优先级高于变量
        console.log(value); // 会输出函数的定义
        var value = 123;
        function value() {
            console.log("fn value");
        }
        console.log(value); // 会输出123
        /*
        function value() {
            console.log("fn value");
        }
        var value;
        console.log(value);
        value = 123;
        console.log(value);
        */

你可能感兴趣的:(js语法基础)