js的内容

本文详细介绍了JavaScript的发展背景、特点、引用方式、变量类型、运算符、条件判断及数组操作等内容,深入讲解了JavaScript的基础知识和常用语法,包括ES6的新特性。JavaScript是一种轻量级、基于面向对象的解释型语言,常用于网页行为控制。文章通过实例展示了变量声明、数据类型转换、运算符的使用以及数组的操作方法,还涉及到了ES6中的let关键字、箭头函数和模板字符串等新特性。
摘要由CSDN通过智能技术生成

1. JS的背景

 W3C将网页的标准分成了三部分:

            HTML        页面的结构

            CSS         页面的样式

            JavaScript  页面的行为

        JavaScript(JS)

            - 发展背景

            - 创建JavaScript的初衷

            - JavaScript最开始由网景公司创建的,参考了当时最火热编程语言java

            - ECMA(欧洲计算机制造联合会)

            - JavaScript被 ECMA组织更名为   ECMAscript(ES)

2--JS的特点

 JavaScript是一门轻量级、基于面向对象的、即时编译的一门解释型语言。

        - 编程语言:人与计算机交流的语言,

        - 就像人们平时交流使用 中文 、 英文、 德文等

        - 计算机语言按照编译模型进行分类:

            - 编译型  : c语言

                - 编译型语言就是先将代码整体编译后生成一个编译文件,最终交给计算机执行该文件

            - 解释型 : JavaScript、python(JIT: JUST IN TIME)

                - 解释型语言,不会生成一个编译文件,而是解释一行执行一行。

3--js引用方式

js引入到网页的三种方式;

            - 1、行内式 通过 on+事件名 的形式书写js代码

            - 这种方式可以,但不推荐!实际开发中不要使用

            - 2、内部引入式  (通过html中script标签)

            - 3、外部js文件的引入  

                - 注意:使用外部js文件引入,需要通过src属性去指定js文件的路径

                -  src属性它具备阻塞页面的能力,它会将src所指引的文件全部下载完毕后,才会执行后面的内容

                -  所以,通常会将外部js文件的引入标签放到body的末尾

4--变量类型     

 基本的数据类型: Number String Boolean  Symbol

        两空: Null 、 Undefined

        变量是保存数据的容器

        JavaScript是一门弱类型语言,动态的  

        typeof  运算符 可以检测对应变量的类型

5--变量转换

    数据类型的相互转换:

                - 强制转换 (人为)

                - 隐士转换(自动转换)

6--运算符

算术运算符

\+   -    *    /    %   ++(自加)   --(自减)   **(幂运算)

+ ++是自加1, 放在变量前,先自加1,再参与运算; 放在变量后,先参与运算,再自加1

+ --是自减1,放在变量前,先自减1,再参与运算; 放在变量后,先参与运算,再自减1

<script>

        let a = 3, b = 2;

        console.log(a + b); //5

        console.log(a - b); //1

        console.log(a * b); //6

        console.log(a / b); //除法, 1.5

        console.log(a % b); //模运算,取余数, 1

        console.log(a ** b); //幂运算, a 的  b次方,   9


 

        console.log(a + b++); //b++, b变量自己加1,  等效于 b = b + 1。  ++放在变量的后面,先参与当前语句的运算,然后再自加

        console.log(b); // b = 3

        console.log(a + ++b); //++b, b变量自己加1,++放在变量的前面, 先自加,然后再参与语句的运算

        console.log(b);// b = 4

        console.log(a-- + b); // -- 自减1, --放在变量之后,先参与运算, 再自己减1

        console.log(a); //a = 2

        console.log(--a + b); // -- 放在变量之前, 先自减1, 再参与运算

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

 // ++ 和 -- 可以独立成为一条语句

        a++;

        b--

        ++a;

        --b;

    </script>

(1) 比较运算符

 <     ==    ===(全等)    >=     <=   !=(不等于)       !==(不全等)

<script>

        let a = 3, b = 2;

        let c = 2;

        let d = "2";

        console.log(a > b); //true

        console.log(a < b); //false

        console.log(a == b); //false

        console.log(b == c); //true

        console.log(b === c); //true


 

        console.log(c == d);// true

        console.log(c === d); //false, 一个是数字类型,一个是字符串类型, 所以类型不等

        console.log(b >= c);//true

        console.log(b <= c); //true

        console.log(b != c); //false

        console.log(c !== d); //true

    </script>

逻辑运算符

&&   与,   || 或, !  非,  ~ 异或,   &  按位与,  |  按位或

<script>

        let a = true;

        let b = false;

       

        // && 只有当两个条件都为真的时候,返回的结果才是true, 否则(一真一假, 或者两个都为假)返回的是false

        console.log(a && b); //false

        console.log(a && a); //true

        console.log(b && b); //false

        // || 只要有一个条件为真,返回结果就为true

        console.log(a || a); //true

        console.log(a || b); //true

        console.log(b || b); //false

        //! 返回相反的结果

        console.log(!a);  //false  

        console.log(!b);  //true

        let m = 5;

        let n = 3;

        // 也可以对表达式进行逻辑运算

        console.log( m>n && m==n); //false

        console.log(m>n || m==n); // true

        console.log(!(m > n)); //false

        let i = 5;

        let j = 2;

        // 5:  101

        // 2:  010

        // &:  000  

        // |   111

        console.log(i & j); //0

        console.log(i | j); //7

        // console.log(~i); //对二进制的每一位取反

    </script>

 三目运算符

根据第一个表达式的值,决定返回后两个结果中的哪一个(true, 返回第一个; false, 返回第二个)

        //语法结构: boolean expression ? result1 : result2  

        let b = true;

        let m = 3, n = 2;

        let result = b ? 1 : 0;

        console.log(result);

        result = !b ? 1 : 0;

        console.log(result);

        //判断性别

        let sex = 0; //1-男; 0-女

        console.log(sex == 1 ? '男' : '女');

    </script>

赋值运算符

= , +=, -=, *=, /=

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <div>

        <p>innerHTML的+=拼接</p>

    </div>

   

    <script>

        let i = 5; //把数值5赋给i变量

        console.log(i += 2);//7, 等效于:   i = i + 2

        console.log(i -= 2);//5,  等效于:  i = i - 2;


 

        //+= 来拼接innerHTML

        let box = document.querySelector("div");

        // box.innerHTML = box.innerHTML + '<p>新的内容</p>';

        box.innerHTML += '<p>新的内容</p>';

    </script>

</body>

</html>

运算符的优先级

从高到低:算术运算符  >  比较运算符  > 逻辑运算符 > 三目运算符 > 赋值运算符

<script>

        console.log(5 > 10 - 2);// 先算10-2, 再算 5>8, 所以返回结果是false

        console.log(5 > 10 - 2 && 3 > 2);// 5 > 8 && 3 > 2,  false && true, false

        let b = 5 > 10 - 2 && 3 > 2;

        console.log(b);

        let i = 5;

    </script>

条件判断

+ if(){  }    只有一个分支,要么执行,要么不执行

+ if(){   }else{      }            两个分支,一定有一个分支被执行,二选一

+ if(){   }else if(){   }else{   }   多分支(相当于if else 嵌套)

</head>

<body>

   

    <script>

        let sex = 1;//1-男; 0-女

        //小括号里面是一个布尔类型的表达式,如果表达式的值为true,大括号里面的代码才会执行

        if(sex == 1){

            console.log('男');

        }

        if(sex == 0){

            console.log('女');

        }

        //if   else。 两种情况(分支),如果……就……否则……

        if(sex == 1){

            console.log('男');

        }else{

            console.log('女');

        }

        //18岁以下少年,18~60岁中青年;60岁以上老年

        // if   else if      else

        let age = 22;

        if(age < 18){

            console.log('少年');

        }else if(age >= 18 && age <= 60){

            console.log('中青年');

        }else{

            console.log('老年');

        }  

        //给出预算,判断能买什么手机200以下,  200~1000, 1000~3000, 3000~5000, 5000以上

        let money = 150;

        if(money < 200){

            console.log('老年机');

        }else if(money >= 200 && money < 1000){

            console.log('小米手机');

        }else if(money >= 1000 && money < 3000){

            console.log('Oppo');

        }else if(money >= 3000 && money < 5000){

            console.log('华为');

        }else{

            console.log('你是土豪,想买啥随意');

        }

    </script>

</body>

 switch case条件判断

<script>

        /*

            switch()括号里面时要判断的变量或表达式

            每一个case就是一个分支, case后面的值要求是一个常量或确定的值,最多只有一个case会被执行

                如果default分支,前面的case都满足条件就执行default.

            每个case后面都有一个break语句,只要有一个case满足条件,后面的case都不会再判断,一直执行直到break结束

        */

        let menu = '文件';

        switch(menu){

            case '文件':

                console.log('创建文件');

                break;

            case '保存':

                console.log("保存文件");

                break;

            case '编辑':

                console.log('修改文件');

                break;

            case '帮助':

                console.log('显示帮助信息');

                break;

            default:

                console.log('其它情况');

                break;    

        }

    </script>

数组

一组数据,存放数据的容器

数组基础

+ 定义数组           []

   new Array()

+ 数组访问

​     数组名字[序号]

+ 数组的长度

   数组名字.length

 <script>

        // 定义数组(声明数组),使用方括号

        let arr1 = []; //定义空数组

        // console.log(typeof arr1);

        // 定义数组并赋值,元素用逗号分割

        let names = ['袁金祥', '罗玉鸿', '郭鹏']; //数组放字符串

        let nums = [1, 3, 5, 7, 9]; //数组放数字

        let booleans = [true, false, true, false, false]; //数组放boolean

        //数组放对象

        let students = [

            {

                name:'张三',

                age: 22

            },

            {

                name: '李四',

                age: 21

            }

        ];

        //数组定义,用Array对象

        let arr2 = new Array(); //空数组

        let arr3 = new Array(2, 4, 6, 8);

        let arr4 = new Array('HTML', 'CSS', 'JavaScript');

        //访问(读写)数组

        console.log(names[0]); //读取数组元素: 数组名[下标],下标从0开始

        console.log(students[0].name);

        names[1] = '罗玉宏';//数组元素的赋值


 

        //数组的长度:length

        console.log(names.length);//数组长度(元素的个数)

       

    </script>

数组操作

+ push()  在数组的后面添加元素

+ pop()   删除并返回数组最后一个元素

+ unshift()  在数组的前面插入一个元素

+ shift() 删除并返回数组第一个元素

+ splice(start, count, element)  删除指定元素或在指定位置插入新的元素

第一个参数:起始位置的下标

第二个参数:要删除的元素的个数(0就不删除)

第三个参数:要插入的新元素,这个参数可以省略

+ concat()  两个数组拼接为一个新数组

+ join()  把数组的元素用参数指定的字符串连接成一个字符串并返回

+ includes()   判断是否包含元素,包含返回true; 不包含返回false

+ indexOf()   返回指定元素的下标 ,如果不存在返回-1

+ lastIndexOf()   返回指定元素在数组中最后一次出现的下标,如果不存在返回-1

<script>

        let names = [];

        console.log(names.length);

        // push()方法往数组的最后添加元素

        names.push('Tom');

        names.push('Jack');

        names.push(88); //js的数组元素的类型可以不同

        console.log(names.length);

        console.log(names);

        // pop() 方法返回数组的最后一个元素,并且把最后一个元素从数组中删掉

        console.log(names.pop());

        console.log(names.pop());

        console.log(names.length);

        //unshift()方法在数组的前面插入元素

        names.unshift('张三');

        names.unshift('李四');

        console.log(names);

        //shift()返回数组的第一个元素,并且把第一个元素从数组中删掉

        console.log(names.shift());

        console.log(names);

        names.push('小红');

        names.push('小明');

        console.log(names);

        /*

            splice() 一是可以删除元素,二是插入新元素

            第一个参数: 起始位置的下标

            第二个参数: 要删除的元素的个数(从当前下标往后面删除),如果为0就是不删

            第三个参数: 插入的新元素,可以省略不写(不会插入)

        */

        names.splice(1, 1, '老王'); //相当于替换

        console.log(names);

        names.splice(1, 2); //删除下标1开始的元素,连续删除两个

        console.log(names);

        names.splice(1, 0, '刘某');//在指定位置插入元素

        console.log(names);

        // concat() 连接两个数组,并返回一个新数组。不影响原来的两个数组

        let arr1 = [1, 3, 5];

        let arr2 = [2, 4, 6];

        let arrNew = arr1.concat(arr2);

        console.log(arr1);

        console.log(arr2);

        console.log(arrNew);

        let arrNew2 = arrNew.concat([100, 101, 102])

        console.log(arrNew2);

        // 克隆新数组

        let arrNew3 = arrNew2.concat([]);

        console.log(arrNew3);

        //join() 把数组元素用指定的分隔符号(参数的字符串)连接成一个字符串

        let str = names.join(",");

        console.log(str);

        console.log(names);

        //includes() 判断数组中是否包含指定的元素,包含返回true;没有包含返回false

        console.log(names.includes('小明'));

        //indexOf() 判断数组中是否包含指定元素,包含返回这个元素的下标;没有包含返回-1

        console.log(names.indexOf('小明'));

        names.push('张三');

        console.log(names);

        //lastIndexOf() 返回数组中最后一个指定元素的下标,如果没有返回-1

        console.log(names.lastIndexOf('张三'));

    </script>

 判断数组类型

    // Array.isArray() 判断一个变量是否是数组,是返回true; 不是返回false

        console.log(Array.isArray(names));

        let arr5 = 100;

        console.log(Array.isArray(arr5));

二维(多维)数组

//二维数组的访问,用两个下标,第一个下标是外层数组的下标,第二个下标是内层数组的下标

        console.log(groups[0][1]);  

        groups[0][1] = '2';    

 循环

##  for循环

for(循环变量; 循环条件; 循环遍历改变){

​       //循环体

}

执行顺序:

​       首先执行1;

​        2, 3, 4   周而复始循环执行,直到循环条件为false才结束

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <ul>

        <li>文件</li>

        <li>编辑</li>

        <li>帮助</li>

    </ul>

    <script>

        // 重复做相同的事情,程序中循环重复执行同一段代码

        for(let i = 0; i < 5; i++){

            console.log(i + '循环代码');

        }

        //循环变量的改变也可以是减少

        for(let i = 5; i > 0; i--){

            console.log(i);

        }

        // 循环变量的定义可以放到for循环之前;循环变量的改变可以放到循环体;甚至循环条件都可以不写(默认为true,死循环)

        // 但是分号不能省略

        let i = 0;

        for(; i < 5;){

            console.log(i);

            i++;

        }        

        // 多个循环变量

        for(let i = 0, j = 10; i < j; i++, j--){

            console.log(i + ', ' + j);

        }

        // 练习:计算从1加到100的结果

        let sum = 0;

        for(let i = 1; i <= 100; i++){

            sum += i;

        }

        console.log(sum);


 

        // 循环终止

        for(let i = 0; i < 10; i++){

            console.log(i);

            if(i == 8){

                break;// 结束循环

            }

        }

        // 跳过某次循环

        for(let i = 0; i < 10; i++){

            if(i == 5){

                continue; //跳过本轮循环,继续执行下一轮循环

            }

            console.log(i);

        }

        // 练习:for循环遍历数组

        let names = ['张三', '李四', '王五'];

        for(let i = 0; i < names.length; i++){

            console.log(names[i]);

        }

        // 通过循环对标签添加事件

        let lis = document.querySelectorAll("ul li");//选择的标签返回数组

        // console.log(lis);

        // 循环标签数组,添加事件

        for(let i = 0; i < lis.length; i++){

            lis[i].addEventListener('click', function(){

                alert(this.innerText);

            })

        }

    </script>

</body>

</html>

循环嵌套

<script>

        // 循环嵌套(两层(重)循环),外层循环没执行一次,内层的循环要全部执行一遍,总的执行次数是外层次数乘以内层次数

        for(let i = 0; i < 5; i++){

            for(let j = 0; j < 5; j++){

                console.log(i + ", " + j);

            }

        }

        // 遍历二维数组

        let arr = [

            [1, 3, 5, 7, 9],

            [2, 4, 6, 8, 10],

        ]

        for(let i = 0; i < arr.length; i++){

            for(let j = 0; j < arr[i].length; j++){

                console.log(arr[i][j]);//i是外层数组的下标,j是内层数组的下标

            }

        }

        // 练习:用*打印10乘5的矩阵

        for(let i = 0; i < 5; i++){

            for(let j = 0; j < 10; j++){

                document.write('*');

            }

            document.write("<br>");

        }

    </script>

for in循环

+ 用于遍历数组

+ 用于遍历对象的属性

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

    <div></div>

    <script>

        // for in用于数组遍历

        let arr = [1, 5, 16, 23, 55];

        // in 关键字后面是数组, 前面自己定义一个变量,它用于接收循环出来的序号

        for(let index in arr){

            console.log(arr[index]); //用序号作为下标去读取数组的元素

        }


 

        // for in 用于对象的属性遍历

        let student = {

            name: '小明',

            sex: '男',

            age: 18

        }

        // in 后面是对象,前面定义的变量接受对象的属性

        for(let key in student){

            // console.log(key);

            console.log(student[key]);  //如果对象的属性是个变量,用[]来读取属性的值

        }

        // 练习:遍历标签对象的style的属性

        let d = document.querySelector("div");

        // console.log(typeof d.style);

        for(let c in d.style){

            console.log(c);

        }

    </script>

</body>

</html>

for of循环

用于数组遍历,遍历出来就是数组元素

不能用于对象属性遍历

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

   

    <script>

        let arr = ['a', 'b', 'c', 'd'];

        // for of 返回的是数组的元素

        for(let el of arr){

            console.log(el);

        }

        // for of不能用于对象属性遍历,它只能用于迭代类型的数据,比如数组,选择的一组标签

    </script>

</body>

</html>

while循环

+ while(){  }    条件为true,继续执行循环;条件为false结束循环

+ do{   }while()    先执行循环,再判断条件,条件为true,继续执行循环;条件为false结束循环

while循环一般用于不知道循环次数的情况

while循环也可以用continue和break语句

<script>

        // 找出10开始的,能被7整除的第一个数

        let i = 10;

        // while循环括号里只有一个布尔类型的表达式,当表达式的值为true,循环继续执行;为false,循环结束

        while( i % 7 != 0){

            i++;

            console.log(i);

        }

        // 用while循环遍历数组

        let arr1 = [2, 4, 6, 8];

        let j = 0;

        while(j < arr1.length){

            console.log(arr1[j]);

            j++;

        }

        // 打印100以内的奇数

        let m = 1;

        while(true){ //死循环,循环体一定要有break语句

            if(m % 2 != 0){

                console.log(m);

            }

            m++;

            if(m > 100){

                break; //终止循环

            }

        }


 

        // do while循环,先执行循环,再判断条件,条件为true继续循环,为false结束

        let x;

        do{

            x = Math.random();//产生一个0~1之间的随机数

            console.log(x);

        }while(x < 0.5)

    </script>

数组的排序和遍历

+ sort()   排序

+ reverse() 倒序

+ forEach() 遍历

+ every() 遍历

+ map() 映射

+ filter() 过滤

<script>

        let arrStr = ['aa', 'bb', 'cc', 'xx', 'dd'];

        //sort()  排序,会影响原数组

        let arrSort = arrStr.sort();

        console.log(arrSort);

        console.log(arrStr);

        // reverse() 颠倒数组元素

        arrStr.reverse();

        console.log(arrStr);

        // 练习:用reverse颠倒单词的字母

        let str = "Hello";

        let arrHello = str.split("");//按照指定的字符串拆分字符串,返回数组

        arrHello.reverse();

        str = arrHello.join(""); //把数组元素取出来,用指定的分隔符拼接成一个字符串

        console.log(str);

        // forEach() 遍历数组

        arrStr.forEach((el, index, arr) => {

            // console.log(el);

            // console.log(index);

            // console.log(arr);

        })

        // every()  遍历数组。靠return结果决定是否继续执行:return true继续执行;return false结束循环

        arrStr.every((el, index, arr) => {

            console.log(el);

            console.log(index);

            console.log(arr);

            if(index > 2){

                return false;

            }

            return true;

        })

        // map()  映射出一个新的数组(把原数组的每个元素进行转换,返回一个新元素)

        let arrNum = [1, 3, 5, 7, 4, 8];

        let arrNumNew = arrNum.map((el, index, arr) => {

            return el * 2;

        })

        console.log(arrNum);

        console.log(arrNumNew);

        //filter() 过滤数组,按条件返回一个新数组

        let arrFilter = arrNum.filter((el, index, arr) => {

            if(el % 2 != 0){

                return true; //当前这个元素会返回给新数组

            }else{

                return false; //不返回这个元素到新数组

            }

        })

        console.log(arrFilter);

       

    </script>

数组查找的方法

+ find()  查找符合条件的第一个对象,并返回。没有找到返回undefined,  如果找到了,后面的元素不再遍历

+ findIndex() 类似与find,返回的元素的下标,如果没有找到返回-1

+ some() 查找是否有符合条件的元素,有返回true, 没有返回false

<script>

        let students = [

            {

                name: '小红',

                age: 16

            },

            {

                name: '小明',

                age: 18

            },

            {

                name: '小王',

                age: 18

            }

        ]

        // 查找年龄18岁的同学

        // find() 查找数组中第一个符合条件的元素并返回(如果找到了就不会再遍历后面的元素).没找到返回undefined

        let result = students.find((el, index, arr) => {

            console.log(el.name);

            return el.age == 18; //返回true就是找到了

        })

        console.log(result);

        // findIndex()  返回符合条件的元素的下标. 没有查找到,返回-1

        result = students.findIndex((el, index, arr) => {

            return el.age == 16;

        })

        console.log(result);

        //some() 查找数组中是否有符合条件的元素,有就返回true, 没有返回false

        result = students.some((el, index, arr) => {

            return el.age == 18;

        })

        console.log(result);

    </script>

```

函数

程序中函数就是能完成特定功能的一段代码的集合

使用函数目的避免代码重复,实现重用

函数定义和使用

+ 没有参数,没有返回值的函数定义和调用

   //函数定义

       //语法:  function 函数名(){

        //

        //    }    

        function sayHello(){

            console.log('Hello HQYJ');

        }

        // 函数调用

        sayHello();

        sayHello();

有参数的函数定义和调用

// 有参数的函数定义和使用

        // name   形式参数,简称形参,参数名随便起名

        // 如果有多个参数,参数之间用逗号分割

        function helloArg(name){

            console.log('Hello ' + name);

        }

        // 调用函数是传递的参数叫实际参数,简称实参

        helloArg('Tom');

        helloArg('张三');

        helloArg('李四', 100);//函数调用时可以传跟形参数量一致的参数,也可以少传,也可以多传

        // 多个参数的函数定义,多个参数用逗号分割

        function add(num1, num2){

            let sum = num1 + num2;

            console.log(sum);

        }

        add(3, 2);//调用多参数函数,实参也是用逗号分割

```

 + 有返回值的函数的定义和使用

        console.log('具有返回值的函数的定义');

        // 具有返回值得函数的定义

        // return 返回函数执行之后的结果,并且结束函数(return 后面的语句不会执行)

        function addReturn(num1, num2){

            let sum = num1 + num2;

            return sum; //函数的返回值

            console.log(sum);

            // return num1 + num2;

        }

        // 调用有返回值的函数后,它会返回一个结果,这个结果可以用于给变量赋值,或者在表达式中参与运算

        let sum = addReturn(10, 20);

        console.log(100 + addReturn(5, 8));


 

        // 函数中有多个return语句,逻辑上保证只有一个return会被执行

        function checkSex(sex){

            if(sex == 1){

                return '男';

            }else{

                return '女';

            }

        }

```

 + 形参的默认值

       // 函数的形参可以设置默认值,给形参赋初始值,如果调用函数时没有传参数,就使用默认值

        function sayMsg(msg = 'HQYJ'){

            console.log('hello ' + msg);

        }

        sayMsg();

        sayMsg('2');

 函数定义的其它场景

  // 函数定义的其它场景

        // 不需要写函数名(匿名函数),用变量名调用

        const sub = function(a, b){

            return a - b;

        }

        console.log(sub(5, 2));

        //匿名函数用于事件

        let btn = document.querySelector('button');

        btn.onclick = function(){

            alert('按钮被点击');

        }

        btn.addEventListener('mouseover', function(){

            alert('鼠标移入');

        })

        // 匿名函数用于事件的方法

        let student = {

            name: '张三',

            age:22,

            study:function(){

                console.log('张三正在努力学习');

            }

        }

        student.study();

        // 箭头函数(朗姆达表达式)定义

        const addLamda = (a, b) => {

            return a + b;

        }

        console.log(addLamda(4, 6));

```

传值调用和传引用调用

+ 传值调用

​       在函数中修改形参的值,不影响调用函数的实参

+ 传引用调用

​       在函数中修改形参的值,会影响实参的值 

<script>

        // 传值(数字,字符串,boolean)调用, 在函数中修改形参的值,不影响调用函数的实参

        function add(a, b){

            a++;

            b++;

            return a + b;

        }

        let x = 6, y = 8;

        let sum = add(x, y);

        console.log(sum);

        console.log('x=' + x + ', y=' + y);



 

        // 传引用(对象)调用,在函数中修改形参的值,会影响实参的值

        let student = {

            name: '小红',

            age: 22

        }

        function changeAge(obj){

            obj.age += 2;

        }

        changeAge(student);

        console.log(student);

    </script>

函数预编译

js在执行之前,先要扫描整个Js代码,会对函数进行预编译处理(登记),还会对函数的形参赋值

预编译完成之后,才从上到下逐行执行js代码,所以调用函数的代码可以放到任意位置,不会像变量一样出现未定义的情况

 <script>

        // console.log(i); //变量的访问是不能在变量定义之前

        let i = 5;

        msg();//函数调用是可以放在函数定义之前

        function msg(){

            console.log('some message');

        }

    </script>

变量的作用域

作用域(scope)就是有效范围

+ 全局:定义在script标签下的的变量是全局变量,它能被当前js任意位置可访问

+ 局部:定义在代码块内的变量称为局部变量,有效范围是当前代码块内

+ 未定义直接赋值的变量默认是全局变量(不管写在什么位置)

<script>

        //直接在script标签下定义的变量,称为全局变量,在当前Js代码的任意位置都可以访问

        let i = 0;

        if(i == 0){

            // 在代码块里定义的变量称为局部变量,只能在当前代码块中能访问,在其他地方不能访问

            let x = 100;

            console.log(i);//可以访问

            console.log(x);

        }

        for(let j = 0; j < 5; j++){

            console.log(i);//可以访问

            //console.log(x);//x 不可访问

        }

        function test(){

            let m = 66;

            if(true){

                console.log(m);//父代码块中的变量可以被子代码块访问

            }

            n = 88; //为声明的变量直接赋值,会变成全局变量

            var p = 99;

            console.log(i);//可以访问

        }

        test();

        //console.log(m);//m不可访问

        console.log(n); //可以访问

        console.log(p); //不可访问

    </script>

自调用函数

 <script>

        // 函数自调用

        //   语法结构:(函数定义)()

        //   如上格式定义的函数不需要调用,它会自动执行(执行一次)。函数可以用匿名函数

        (function(){

            console.log('Hello');

        })()

        (() => {

            console.log('箭头函数');

        })();

    </script>

闭包

## 变量污染的问

如果一个Html页面中引入多个Js文件,这些文件中定义同名的全局变量,就造成变量污染(冲突,重复定义)

这就会导致页面报异常,所以引入闭包的概念,作用就是把变量封闭在自己函数内,别的代码无权访问,这样就不会冲

const 函数名 = ( ()=> {

    let 变量1;

    let 变量2;

    return (参数1, 参数2) => {

        //函数代码

    }

})()

```

案例

一个Html文件中引入两个闭包函数文件

+ html

```html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

</head>

<body>

   

    <!-- 引入独立的js文件 -->

    <script src="./js/sum.js"></script>

    <script src="./js/avg.js"></script>

    <script>

        // 如果引入不同的Js文件,里面出现相同的全局变量名,

        //  这种现象称为全局变量的污染

        //  解决办法使用闭包的写法: 在函数外面套一层自调用函数

        let arr = [23, 56, 18, 57, 90];

        console.log(sum(arr));

        console.log(avg(arr));

    </script>

</body>

</html>

```

+ sum.js

```js

const sum = (() =>{

    let result = 0;

    return function(arr){

        arr.forEach(element => {

            result += element

        });

        return result;

    };

})();


 

```

+ avg.js

```js

const avg = (() => {

    let result = 0;

    return (arr) => {

        arr.forEach(element => {

            result += element;

        });

        result /= arr.length;

        return result;

    }

})()

字符串 

 <script>

        let str = 'hello world !!!';

        // 字符串的长度

        console.log(str.length);

        // 用下标来访问字符串中字符

        console.log(str[6]);//w

        // charAt() 返回指定位置的字符,参数是下标

        console.log(str.charAt(8));//r

        // split() 按指定的字符串拆分字符串,返回数组

        let arr1 = str.split(" ");//['hello', 'world', '!!!']

        console.log(arr1);

        console.log(arr1.join('_'));

        // replace() 替换字符串中第一次出现的指定字符串为新字符串。第一个参数是要替换字符串,第二个参数是新字符串

        console.log(str.replace('!', '.'));//hello world .!!

        // replaceAll()类似replace(), 替换所有相同的字符串

        console.log(str.replaceAll('!', '.')); //hello world ...

        let strBlank = '     ' + str + '            ';

        console.log(strBlank);

        // 去掉字符串左右的空格

        console.log(strBlank.trim());//hello world !!!

        // substring(), 截取字符串,第一个参数是起始位置,第二个参数是结束位置(不包含)

        console.log(str.substring(6, 11));//world

        // 第二个参数可以省略,省略后截取到字符串末尾

        console.log(str.substring(6));//world !!!

        //substr() 截取字符串,第一个参数是起始位置,第二个参数要截取字符的个数

        console.log(str.substr(6, 5));//world

        // startsWith() 判断字符串是否是以指定字符串开头,是返回true, 不是返回false

        console.log(str.startsWith('hello'));// true

        // endsWith() 判断字符串是否以指定的字符串结束,是返回true,不是返回false

        console.log(str.endsWith('!!!'));//true

        // indexOf() 返回指定字符串出现的起始位置(第一次出现的位置)

        console.log(str.indexOf('o'));//4

        // lastIndexOf() 返回指定字符串最后一次出现的起始位置

        console.log(str.lastIndexOf('o'));//7

        // toUpperCase() 字符串中字母全部转大写

        console.log(str.toUpperCase());//HELLO WORLD !!!

        // toLowerCase() 字符串中字母转小写

        console.log(str.toLowerCase());//hello world !!!

    </script>

 Map和Set

<!DOCTYPE html>

<html lang="en">

  <head>

    <meta charset="UTF-8" />

    <meta http-equiv="X-UA-Compatible" content="IE=edge" />

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <title>Document</title>

  </head>

  <body></body>

  <script>

    // Map 的使用类似 json 对象

    // 声明 Map

    let obj = {

      a: 1,

      b: 2,

    };

    let map = new Map([

      ["a", 1],

      ["b", 2],

    ]);

    console.log(map);

    // 读值

    console.log(map.get("a"));

    // 赋值

    map.set("c", 3);

    console.log(map);

    // has 判断是否存在某个 key

    console.log("a" in obj);

    console.log("b" in map);

    console.log(map.has("b"));

    // 迭代map

    let keys = map.keys(); // => keys 方法将返回一个迭代器

    console.log(keys);

    // k 是一个零时变量 用于存储迭代器next方法返回的每一个key

    // k 数据结构为 { value: 'key名称', done: '是否迭代完成' }

    let k;

    // 迭代器都包含一个 next 方法,用于迭代下一个

    while (!(k = keys.next()).done) {

      let v = map.get(k.value); // 通过 key 读取 value

      console.log(`key: ${k.value}; value: ${v}`);

    }

    // 可以使用 forEach 迭代

    map.forEach((value, key, self) => {

      // value 值

      // key 键

      // self map自己

      console.log(`value: ${value}; key: ${key}`);

      console.log(self);

    });

    // for of 可以用来迭代存在迭代器的对象

    // for of 遍历 Map

    for (const kv of map) {

      console.log(kv);

      let key = kv[0];

      let value = kv[1];

      console.log(key, value);

    }

    // Set 是不重复的数据集,若存入多个重复数据会自动去重

    let set = new Set([

      1,

      1,

      2,

      23,

      3,

      3,

      4,

      "hello",

      "hello",

      true,

      true,

      false,

    ]);

    console.log(set);

    // 添加

    set.add(123);

    console.log(set);

    // 读取set长度

    console.log(set.size);

    // 删除

    set.delete("hello");

    console.log(set);

    // 判断是否存在某个值

    console.log(set.has(5));

    // 迭代 set

    let vs = set.values(); // values 方法返回一个迭代器

    let v;

    while (!(v = vs.next()).done) {

      console.log(v); // v 的内容和 map 相同为 {value: '集合中的每个成员', done:'是否迭代完成'}

      console.log(v.value); // v.value 就是集合中的成员

    }

    // for of 遍历 Set

    for (const value of set) {

      console.log(value);

    }

    console.log("set foreach");

    // foreach 迭代 set

    set.forEach((value, key, self) => {

      console.log(value);

      console.log(key);

      console.log(self);

    });

    // 通过 set 转换成数组

    // 可以通过这种方法来让数组去重

    let arr = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5];

    set = new Set(arr);

    // 将set转换回数组

    arr = Array.from(set);

    console.log(arr);

  </script>

</html>

 ES6语法

<!DOCTYPE html>

<html lang="en">

  <head>

    <meta charset="UTF-8" />

    <title>Title</title>

  </head>

  <body></body>

  <script>

    // let 关键字

    let x = 1;

    var y = 1;

    // let 比 var 拥有更明确的作用域,它只会在声明它的代码块中可访问

    for (var i = 0; i < 10; i++) {

      setTimeout(() => {

        console.log(i);

      });

    }

    for (let i = 0; i < 10; i++) {

      setTimeout(() => {

        console.log(i);

      });

    }

    // ... 三个点能将数组和对象中的内容拆出来并用 “,” 逗号隔开

    let obj = { a: 1, b: 2, c: 3 };

    let obj2 = { x: 1, y: 2, z: 3 };

    // ...obj => a: 1, b: 2, c: 3

    let arr = [1, 2, 3];

    let arr2 = [4, 5, 6];

    // ...arr => 1, 2, 3

    // 使用 ... 扩展对象

    obj = { ...obj, ...obj2 };

    console.log(obj);

    // 使用 ... 克隆对象

    let result = { ...obj };

    // 使用 ... 扩展数组

    arr = [...arr, ...arr2];

    console.log(arr);

    // 使用 ... 克隆数组

    result = [...arr2];

    console.log(result);

    // lamda 表达式 也称 箭头函数

    let fn = () => {};

    // 带参数

    fn = (a, b, c) => {};

    // 如果参数只有一个,可以省略括号

    fn = (x) => {};

    // 箭头函数的箭头后面可以省略花括号

    fn = () => "hello world"; // 箭头后面的内容就是函数返回值

    fn = () => ({ x: 1, y: 2 }); // 返回对象要在箭头后面打圆括号

    // const 定义常量 常量是readonly只读的属性

    // 一旦初始化后 就不能修改其值

    const PI = Math.PI;

    // 模板字符串

    let d = new Date();

    let year = d.getFullYear();

    let month = d.getMonth() + 1;

    let date = d.getDate();

    let str = `${year}/${month}/${date}`;

    console.log(str);

    // 模板字符串换行输出

    str = `

    123

          456

              789


 

    hello

    `;

    console.log(str);

    // 解构

    obj = { a: 1, b: 2 };

    // 结构赋值

    // 对象的解构赋值

    // 若 obj 存在属性 a 则将 obj.a 赋值给变量 a

    // 同理 若 obj 存在属性 b 则将 obj.b 赋值给变量 b

    let { a, b } = obj;

    console.log(a, b);

    // 数组的结构赋值

    // 数组会将对应索引位置的成员赋值给变量

    // 例如 此处的 0 号成员 赋值给变量 a

    // 1 号成员赋值给变量 b

    arr = ["a", "b", "c"];

    [a, b] = arr;

    console.log(a, b);

    // 函数参数中使用解构

    function logUser({ name, sex }, age) {

      console.log(`${name}: ${sex}: ${age}`);

    }

    function logUser2([name, sex], age) {

      console.log(`${name}: ${sex}: ${age}`);

    }

    logUser({ name: "张三", sex: "male" }, 16);

    logUser2(["李四", "female"], 24);

    // 函数的 rest 参数(parameter)

    // rest 参数 仅出现在参数列表的最后一个位置上

    function logNames(a, b, ...c) {

      // 变量 c 将作为数组使用

      console.log(a, b, c);

    }

    // rest 参数的位置 可以传入任意多个参数

    // 从 rest 参数开始 所有的参数值都会被存入到数组 c 中

    logNames("x", "y", "z", "a", "b", "c");

    // 定义对象属性和方法的简写

    let name = "隔壁老王";

    let age = 30;

    let sayHello = () => {

      console.log("hello");

    };

    let user = {

      // 当属性名和属性值的变量名相同时,可以省略冒号后面的内容

      name,

      age,

      sayHello,

      // sayGoodBye: function () {},

      // 对象方法可以简写如下:

      // 去掉 : 冒号和函数的关键字 function

      sayGoodBye() {

        console.log("good bye");

      },

    };

    // ? 问好语法

    // 判断是否存在,存在就执行,否则不执行

    user = null;

    user?.sayHello();

    // user?sayHello() 等价于下列代码

    if (user) {

      user.sayHello();

    }

  </script>

</html>

 delete关键字

<script>

    // delete 删除 对象属性,对象行为

    let obj = {

      x: 1,

      y: 2,

      sayGreet: () => {

        console.log("greeting");

      },

    };

    // delete 语法:

    // delete object.attrName

    // 删除属性如下

    delete obj.x;

    delete obj.sayGreet;

    console.log(obj);

    // 删除数组成员

    let arr = [1, 2, 3];

    delete arr[1];

    console.log(arr);

    // 一般不会用 delete 删除数组成员 因为会留下一个 empty 占位

    // 所以请使用 arr.splice 删除数组成员

    // 不要直接删除变量 这是不规范的

    // 若要想删除变量 请赋值 undefined 代替

    obj = undefined;

  </script>

 instanceof关键字

<script>

    // instanceof : 用于判断一个实例是否属于某个类型

    // 语法:object instanceof class

    // 该表达式返回一个布尔值,true:代表object属于class的类型,否则不属于

    class Human {

      name;

      sex;

      constructor(name, sex) {

        this.name = name;

        this.sex = sex;

      }

    }

    let xiaoHong = new Human("小红", "女");

    let zhangSan = new Object();

    // 判断小红是否属于人类

    console.log(xiaoHong instanceof Human); // --> true

    console.log(xiaoHong instanceof Object); // --> true

    // 判断张三是否属于人类

    console.log(zhangSan instanceof Human); // --> false

    console.log(zhangSan instanceof Object); // --> true

    // instanceof 一般用于服务器上,用来判断自定义异常类型

    // 自定义异常类

    // 类型异常

    class TypeError extends Error {

      constructor(msg) {

        super(msg);

      }

    }

    // 除数为0异常

    class ChuShuIsZeroError extends Error {

      constructor() {

        super("除数不能为 0");

      }

    }

    function div(x, y) {

      if (typeof x !== "number") {

        // 若 x 不是数字抛出类型异常

        throw new TypeError("x 不是数字");

      }

      if (typeof y !== "number") {

        // 若 y 不是数字抛出类型异常

        throw new TypeError("y 不是数字");

      }

      if (y === 0) {

        throw new ChuShuIsZeroError();

      }

      return x / y;

    }

    try {

      let result = div(1, 2);

      console.log(result);

    } catch (error) {

      // 使用 instanceof 判断异常对象的类型

      if (error instanceof TypeError) {

        console.log("参数类型异常");

        console.log(error.message);

      } else if (error instanceof ChuShuIsZeroError) {

        console.log("除数为0");

        console.log(error.message);

      } else {

        console.log(error);

      }

    }

  </script>

 lamda表达式返回值的简写

 <script>

    // 声明一个箭头函数

    let add = (x, y) => {

      return x + y;

    };

    // 为了方便,可以简写返回值

    // 省略函数的花括号 代表直接返回箭头后的内容

    add = (x, y) => x + y;

    console.log(add(1, 2));

    // 箭头函数返回对象

    add = (x, y) => {

      return {

        he: x + y,

      };

    };

    // 简写

    add = (x, y) => ({ he: x + y });

  </script>

 原型链

<script>

    // 什么是原型链?

    // 原型链是由原型构成的一个层层访问的引用链条

    function A() {

      this.name = "张三";

    }

    function B() {

      this.age = 17;

    }

    // B 继承 A

    B.prototype = new A();

    function C() {

      this.sex = "male";

    }

    // C 继承 B

    C.prototype = new B();

    let c = new C();

    console.log(c.sex);

    console.log(c.age); // c.__proto__.age

    console.log(c.name); // c.__proto__.__proto__.name

    // 当访问子类实例的属性时,js先会从子类实例中查找是否存在该属性,若不存在则向其原型中查找是否存在该属性,若不存在就继续从原型的原型中查找,直到查到或找不到为止

  </script>

 。this关键字

<script>

    // 参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/this

    // this 关键字代表什么?

    // 非严格模式下,根据不同的场景,this关键字代表东西不同,有以下几种情况

    // 非严格模式下的this

    // js 执行上下文中的 this

    console.log(this); // => window (当前环境下的全局变量)

    // 函数内的this

    function fn() {

      console.log(this); // => window

    }

    // 对象方法的this

    let obj = {

      name: "张三",

      fn: function () {

        console.log(this); // 对象方法中的this 代表该对象自身

        fn2();

        function fn2() {

          console.log("fn2");

          console.log(this); // => window

        }

      },

      fn2: () => {

        console.log(this);

      },

    };

    // 对象方法的this

    class A {

      fn() {

        console.log(this);

        fn2();

        function fn2() {

          console.log("fn2");

          console.log(this); // => undefined

        }

      }

    }

    // 对象方法中的this始终是自己

    let a = new A();

    a.fn();

    // 声明变量存储 A 类的 fn 函数,再次调用并观察 this

    // 给变量赋值函数值,默认情况下 this 为 undefined

    let fnOfA = a.fn;

    fnOfA();

    // 有些情况下,回调函数中的this可能被其他函数赋值,所以this不是undefined

    // 此处 事件回调函数被 addEventListener 赋值了其中的 this

    // 所以这里的this指的是绑定事件的那个dom对象

    const btn = document.querySelector("button");

    btn.addEventListener("click", function () {

      console.log(this);

    });

    // 总结:

    // 1. js 执行上下文 => window

    // 2. 执行上下文下声明的函数内 this => window

    // 3. 方法内的this始终是方法所在对象自身

    // 4. this 可能被其他函数赋值 例如 addEventListener 这种时候 this 既不是 window 也不是 undefined,它取决于函数 addEventListener 自己

  </script> -->

  <script>

    "use strict";

    // 结论:

    // 1. js 执行上下文 => window

    // 2. 只要是函数 this 就是 undefined

    // 3. 方法内的this始终是方法所在对象自身

    // 4. this 可能被其他函数赋值 例如 addEventListener 这种时候 this 既不是 window 也不是 undefined,它取决于函数 addEventListener 自己

    console.log(this); // => window

    function fn() {

      console.log(this); // => undefined

    }

    let obj = {

      fn() {

        console.log(this); // => obj

        fn2();

        function fn2() {

          console.log(this); // => undefined

        }

      },

    };

    class A {

      fn() {

        console.log(this); // => a

        fn2();

        function fn2() {

          console.log(this); // => undefined

        }

      }

    }

    let a = new A()

    // a.fn()

    let fnOfA = a.fn

    fnOfA()

  </script>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值