Bootstrap

JavaScript

第一章javaScript基本使用

1.输入输出语句

a.输出语句

用于在浏览器中弹出警告

 alert("未满十八岁禁止访问");

用于在控制台中输入信息           

  console.log('111');

用于在网页中输出内容

  document.write("三月请对我好一点")

b.输入语句

在网页中弹出一个输入框             

prompt("请输入姓名")

在网页中弹出一个确认框

   confirm("你真满十八岁了吗")

2.JS代码引入方式

a.js行内式写法 

            onclick点击事件 

<button onclick="window.alert('别点了,再点就要xx')">请点我</button>

b.嵌入式      

<script>window.alert("内部样式")</script>

c.外链式 

<script src="./3-外链式.js"></script>

第二章javaScript基本语法

1.变量的声明与赋值

a.先声明后赋值

声明变量     

var boy;

        var girl;

        console.log(boy);  //underfined(未定义的)

        console.log(girl);

为变量赋值     

  boy = 'jack'

        girl = "lily"

        console.log(boy);

        console.log(girl);

b.声明的同时并赋值

       

 var myAge = 16;

        var myHeight = 18;

        console.log(myAge);

        console.log(myHeight);

2.let声明变量

let是ES6新引入的关键字,用来替代var关键字

ES6指2015年推出的ECMAScript语法

注:使用var声明的变量,可以多次赋值,但是结果只与最后一次赋值有关

       

var boyFriend = "魏大勋"

        var boyFriend = "魏晨"

        var boyFriend = "白敬亭"

        console.log(boyFriend);

注:let 不允许在一个代码块里有变量取同样名字,但允许修改同一个变量值

 一个花括号就是一个代码块   

 let girlFriend = "蔡徐坤"

   girlFriend = "李易峰"

   console.log(girlFriend);

   { let girlFriend = "蔡徐坤" }

3.const声明变量

a.let/var声明可以改变,

b.const声明的变量不能改变,即常量。

(1)初始化要求不同,

    使用var和let声明变量时可以先不初始化,而使用const声明变量时必须初始化。

    (2)重复声明不同,

    使用var和let声明的变量可以多次被修改,其值只与最近一次赋值一致,而使用const声明的变量,在整个运行过程中不能修改初值.

    (3)对块级作用域的支持不同。

    (使用一对花括号括起来的代码称为一个代码块所谓块级作用域,

    就是指变量起作用的范围是当前代码块,离开当前代码块,变量就失效了。

    使用var声明的变量支持全局作用域,使用let和const声明的变量支持块级作用域。)

错误写法:         

const a=3.14

         a=3.15

         cosole.log(a);

正确写法       

 const a = 3.14

        console.log(a);

c.const必须在声明的时候就赋值;

4.var/let和const的不同

(1)初始化要求不同,使用var和let声明变量时可以先不初始化,而使用const声明变量时必须初始化。

 (2)重复声明不同,使用var和let声明的变量可以多次被修改,其值只与最近一次赋值一致,而使用const声明的变量,在整个运行过程中不能修改初值.

 (3)对块级作用域的支持不同。

 (使用一对花括号括起来的代码称为一个代码块所谓块级作用域,

 就是指变量起作用的范围是当前代码块,离开当前代码块,变量就失效了。

  使用var声明的变量支持全局作用域,使用let和const声明的变量支持块级作用域。) 

5.数据类型分类

简单数据类型存储在栈内存中,

复杂数据类型的内存存储在堆内存中,地址存储在栈内存中

6.基本数据类型

a.Boolean-布尔型

                                :true/false

b.number-数字型

let age = 18;

let date = "0306"

console.log(age);

console.log(date);

console.log(Number.MAX_VALUE);//最大值

console.log(Number.MAX_VALUE * 2);//Infinity(无穷大)

var a = 3 - "b"

console.log(a);//NaN (not a number) NaN也属于数字类型

 c.isNaN判断是否是 非数字型

       

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

        console.log(isNaN(111));//false

c.string-字符串

        let demo1="字符串";
 
        let demo2='字符串';
 
        let demo3='字符串';
 
        let demo4="老师说'今天晚上不上晚自习'"


 

d.underfined-未定义型

表示声明的变量未赋值

let grade;

console.log(grade);//underfined

e.null-空型

   var a = null;
 
   console.log(a); //null

h.数据类型检测

       

isNaN 检验是否是一个非数字
        typeof()
console.log(typeof ("123"));//string
console.log(typeof (false));//boolean

console.log(typeof (NaN));//number

console.log(typeof (Infinity));//number

console.log(typeof ("true"));//string

console.log(typeof (undefined));//underfined

console.log(typeof (null));//object  

console.log(typeof ('aaa' * 2));//number

console.log(typeof ('aaa' * 2));//NaN

boolean类型true 会在运算中转化为 1

false会转化成 0



加好遇上字符串,做拼接使用

        console.log(2+"true");//2true

        console.log(typeof(2+"true"));//String

7.数据类型转换

a.将数据类型转化为布尔类型

字符串类型和数字类型都会转化为布尔类型的true        

空字符串转为布尔类型的false,空格字符串转为true

        Boolean()
        var a = Boolean("a")

        console.log(a);//true

        console.log(Boolean(123));//true

        console.log(Boolean(""));//false

        console.log(Boolean(" "));//true

        console.log(Boolean(0));//false

        console.log(Boolean(NaN));//false

        console.log(Boolean(undefined));//false

        console.log(Boolean(null));//false

b.将数据转换为字符串类型

使用String()或者toString()转换
let num=true;

console.log(num);//数字类型的1

let num2= String(num)

console.log(num2);//1字符串类型1

c.将数据转化为数字型数据

Number()用于将数据转换成数字型数据
console.log(Number(123));//123

console.log(Number("123"));//123

console.log(Number(""));//0

console.log(Number(" "));//0

console.log(Number(null));//0

console.log(Number(undefined));//NaN

console.log(Number(false));//0

console.log(Number(true));//1

console.log(Number("true"));//NaN

console.log(Number("123.a"));//NaN

8.运算符

a.算数运算符

9.字符串运算和隐式转换

 隐式转换:当两个数据类型不同时,JS会按照既定的规则进行转换。

 字符串运算符:加号遇上字符串,做拼接使用。

10.赋值运算符

11.比较运算符

注释:

        ==和!=在比较不同数据类型时,会将比较的数据转化为相同的类型数据

===和!===则不会进行数据类型的转换

12.逻辑运算符

 && 逻辑与运算符 一假则假

                 

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

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

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

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

 例:       

        console.log(3>2 && 2>1);//true

        console.log(3<2 && 2>1);//false

|| 逻辑或运算符 一真则真

例:console.log(true||true);//true

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

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

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

 ! 逻辑非运算符 真做假来假作真

console.log(!true);//false
        console.log(!(2 > 1));//false
        console.log(!(2 < 1));//true
// 闰年的判断能被400整除或者4整除,但不被100整除的年份
        var year;
        var run = (year % 4 == 0 && year % 100 != 0 || year % 400);
        var result = run ? "闰年" : "平年" //三元表达式
        console.log(result);

        

13.三元运算符

//条件表达式 ? 表达式1 : 表达式2

        // 如果条件表达式的值为true,则返回表达式1的执行结果,
        // 为false,则返回表达式2的执行结果

        var age = prompt("请输入你的年龄")
        console.log(age);
        var res = age >= 18 ? "你已经是一名优秀的成年人了" : "你还是个宝宝"
        document.write(res)

14.运算符优先级

15.选择结构

a.if语句

    if(条件表达式){代码段}

    let age = prompt(请输入你的年龄)

    if (age >= 18) {

    document.write("你可以进入网站")
    }

    
b. if.. else 语句

    if(条件表达式){

    代码段

    }else{代码段2}

    let age = prompt("请输入你的年龄")

    if (age >= 18) {

        document.write("你可以进入本网站")

     } else {

        document.write("非法访问")

     }

     
c. if..else if..else语句(多分支)    

     if(条件表达式1){

        结果

     }else if(条件表达式2){

        结果

     }else{}

d.swich语句

      switch(表达式){
            case 值1:
            代码段;
            break;
            case 值2:
            代码段;
            break;
            .   
            .   
            .
            default
            代码段;
            }

16.循环语句

a.for语句


        for (初始化变量; 条件表达式; 操作表达式) {
            循环体
        }
        let sum = 0;
        for (var i = 1; i <= 100; i++) {
            if (i % 2 == 0) {
                sum += i
            }
        }
        console.log(sum);

b.while语句 


        while(条件表达式){
            循环体
        }

        var i = 1;
        while (i <= 100) {
            console.log(i);
            i++;
        }
        var name = prompt("请输入用户名")
        var password = prompt("请输入密码")
        while (name != 'admin' && mima != '123456') {
            prompt("请重新输入");
            prompt("请输入用户名");
            prompt("请输入密码");
        }
        alert("登入成功")

c.do..while语句

        while语句先判断条件表达式的值,再根据条件表达式的值是否执行循环体

        do...while语句会无条件先执行一次,再进行判断条件表达式的值是否进入循环

do{
  循环体
}while{表达式}

17.跳转语句

a.break语句

break语句是跳出整个循环,直接循环结束

        for (var i = 1; i <= 5; i++) {
            if (i == 3) {
                console.log("吃到了毒苹果");
                break;//跳出整个循环
            }
            console.log("我吃完了第" + i + "个苹果");
        }

b.continue语句

continue语句用来跳出本次循环,跳过continue语句后方的代码

        for (var i = 1; i <= 5; i++) {
            if (i == 3) {
                console.log("吃到了毒苹果");
                continue;//跳出本次循环
            }
            console.log("我吃完了第" + i + "个苹果");
        }

18.循环嵌套

            var str = '';
            // 成列
            for (var i = 1; i <= 4; i++) {
            // 成行
            for (var j = 0; j <= 4; j++) {
                str += "*"
            }
            // "\n换行
            str += "\n";
            console.log(str);
            }
            如果输入的不是数字,就转换为NaN
            确保输入的是纯数字。
            a = Number(a) && parseInt(a)

            console.log(Number(null));//0

            console.log(parseInt(null));//NaN

            console.log(parseInt("123.a"));//123

            console.log(Number("123.a"));//NaN

            逻辑与符号必须均满足Number和parseInt的效果

            如果有一方不满足,n的结果就是NaN

            那么isNaN(n)的值就为true。

第三章 数组

1.初始数组

        数组是一种复杂数据类型
        用于将一组数据集合在一起
        通过一个变量就可以访问一组数据
        数组中元素是用逗号隔开
        数据中的'索引/下标',是从0开始计算的
        // 声明数组
        let class02 = ["tom", 'lily', 'tony']
        // 打印数组
        console.log(class02);
        // 打印数组长度
        console.log(class02.length);
        // 打印数组中下标为x的元素
        console.log(class02[1]);//lily
        console.log(class02[0]);//tom

        //数组可以是任意类型元素 
        // 例如:字符串 数组 数字
        let arr1 = [1, 2, 3, 4, 5, 6];
        let arr2 = ['string', NaN, null, undefined]
        console.log(arr2);

2.创建数组

①. 以new Array()方式创建数组

        var arr = new Array();
        console.log(arr);//Array(0)
        var arr = new Array(5);
        console.log(arr);//[empty*5]
        arr = new Array("tom", "tony", "bob");
        console.log(arr);

②.使用数字字面量创建数组

        var mood = ['sad', , , , , , , 'happy']
        console.log(mood.length);//8
        console.log(mood[7]);//happy
        console.log(mood[6]);//undefined
        console.log(mood[0]);//sad

3.数组的基本操作

① 获取元素长度

数组名 .length

②修改数组长度       

数组名 .length = number

        var arr = [0, 1, 2, 3];
        console.log(arr.length);//4
        arr.length = 5;
        console.log(arr); // [0,1,2,3,empty]

③添加数组长度

        arr[4] = 3;
        console.log(arr);//[0,1,2,empty,3]

④修改数组元素

        arr[0] = 1;
        console.log(arr);//[1,1,2,empty,3]

⑤删除数组元素内容

        delete arr[1];
        console.log(arr);

⑥遍历数组

        let arr1 = [10, 20, 30, 40, 50, 60]
        let sum = 0;
        for (var i = 0; i < arr1.length; i++) {
            sum += arr1[i]
        }
        console.log(sum);

⑦新增数组

      //push在数组后添加元素
        let arr3 = [1, 2, 3, 4]
        arr3.push(5, 6)

      //unshift在数组前面添加内容
        arr3.unshift(-2, -1, 0)
        console.log(arr3);

4.二维数组

        //二维数组指的是数组元素的值是一个一维数组
        var arr = [80, 100, 75]
        var arr1 = [
            [80, 100, 75],
            [90, 67, 66],
            [99, 87, 85],
        ]

        // 访问二维数组
        console.log(arr1[0]);//[80, 100, 75]
        console.log(arr1[0][0]);//80

        for (var i = 0; i < arr1.length; i++) {
            console.log(arr1[i]);
            for (var j = 0; j < arr1[i].length; j++) {
                console.log(arr1[i][j]);
            }
        }

        //二维数组倒置
        var arr = [
            ['a', 'b', 'c'],
            ['d', 'e', 'f'],
            ['g', 'h', 'i'],
            ['j', 'k', 'l'],
        ];
        var res = [];
        // 遍历原数组的行
        for (var i = 0; i < arr.length; i++) {
            //根据原数组的行,设置新数组的列
            res[i] = [];
            // 遍历原数组的列
            for (var j = 0; j < arr[i].length; j++) {
                //j是原数组的列 i是数组的行
                //颠倒位置
                res[j][i] = arr[i][j];
            }
        }



        // 计算出每一位同学的总成绩
        var stu = [
            [88, 70, 60, 60],
            [66, 46, 60, 80],
            [90, 70, 88, 93],
        ]

        for (var i = 0; i <= stu.length; i++) {
            console.log(stu[i]);
            var sum = 0;
            for (var j = 0; j < stu[i].length; j++) {
                sum += stu[i][j];
            }
            console.log('第' + (i + 1) + '位的学生的总成绩是' + sum);
        }

5.map数组遍历器 

        //需求:将arr数组中每个元素加1,生成新数组;
        let arr = [23, 31, 69, 100, 106];
        let arr1 = []
        for (var i = 0; i < arr.length; i++) {
            arr1[i] = arr[i] + 1
        }
        console.log(arr1);
        // Map:利用某种规则映射得到一个新数组
        // map()中需要传入一个回调函数作为参数
        // 在回调函数中定义需要map数组遍历方法做什么事情
        // arr.map(元素,下标) =>{return 新元素}
        let rse = arr.map(function (value, index) {
            return value + 1
        })
        console.log(rse);


        let rse2 = arr.map(function (value, index) {
            return value * 2;
        })
        console.log(rse2);

6.数组过滤器

        var arr = [-10, 0, 10, 20, 30]
        var rse = []
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] > 10) {
                rse.push(arr[i])
            }

        }
        console.log(rse);
        //filter:用于筛选数组中满足条件的元素,返回筛选后的新数组
        // arr.filter(value,index)=>{筛选条件}
        // filter形成的新数组的长度 != 原数组长度
        // 回到函数执行次数==数组长度
        let res2 = arr.filter((value, index) => {
            return value > 10;
        })

        var res1 = [-20, 30, 50, 70, 95, 54]
        let res3 = res1.filter((value, index) => {
            return value % 2 == 0;
        })
        console.log(res3);

7. forEach数组遍历

        let arr = [1, 2, 3, 4, 5, 6]
        var sum = 0;
        for (var i = 0; i < arr.length; i++) {
            sum += arr[i]
        }
        console.log(sum);

        let sum1 = 0;
        arr.forEach(value => { sum1 += value });
        console.log(sum1);
        // forEach也是用户遍历数组
        // 数组名.forEach(function(value,index,arr){
        // 算法
        // })
        // 回调函数执行次数==数组长度
        // forEach没有返回值,不需要return

 8.some判断ture/false

        //some判断数组元素是否符合条件

        let arr = [-1, 1, 2, 3, 4, 5]
        //判断数组中有没有负数

        for (var i = 0; i < arr.length; i++) {
            if (arr[i] < 0) {
                a = true;
                break;
            }
            a = false
        }
        console.log(a);

        let res = arr.some((item, index) => {
            return item < 0
        })
        console.log(res);

        //回调函数执行次数!==数组长度
        //some 函数返回布尔值
        //只要一个函数符合函数体的判断条件就返回ture 反之则返回false

        let year = [2001, 2002, 2003, 2005]

        let res1 = year.some((item, index) => {
            return item % 4 == 0 && item % 100 != 0 || item % 400 == 0;
        })
        console.log(res1);

9.every 

        //some和every遍历函数后返回的都是一个布尔类型的值
        //如果有元素满足条件,some的值为true
        //当全部元素满足条件时,every的值为true


        //判断数组中是否全部为正数,全为正数则返回true,反之则为false
        var arr1 = [1, 2, 1, 4, 5, 6]
        for (var i = 0; i < arr1.length; i++) {
            var a = true;
            if (arr1[i] < 0) {
                a = false;
                break;
            }
        }
        console.log(a);

        let res = arr1.every(function (item) {
            return item > 0;
        })
        console.log(res);

10.findIndex

        //findIndex用于返回第一个符合元素的下标

        var arr = [9, 4, 0, -1, 3, -2, 7]

        // 需求:找到一个非正数的下标并返回

        for (var i = 0; i < arr.length; i++) {
            if (arr[i] < 0) {
                console.log(i);
                break;
            }
        }

        //需求:使用findIndex完成arr非负数下标的寻找
        let res = arr.findIndex(function (item) {
            return item < 0;
        })
        console.log(res);
        // var index = arr.findIndex( val => val < 0)console.log(index);

11.reduce 

        var arr = [97, 66, 48, 31, 82]

        //求数组各项的平均值
        var sum = 0;
        for (var i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        console.log(sum / arr.length);


        let res = arr.reduce((item, index) => item + index)
        console.log(res / arr.length);

第四章 函数

1.初识函数

            函数定义:函数用于封装完成一段特定的功能的代码,

            将一条或者多条语句,组成的代码块包裹起来

            用户在使用时,只需要关系参数和返回值,就能完成特定的功能,

            不用了解具体的代码。
        // 内置函数:
        console.log(isNaN("number"));//true
        console.log(parseInt("15.99"));//15

        // 无参函数:
        function demo() {
            console.log("我是一个函数");
        }
        demo()//我是一个函数

        // 有参函数
        function sum(a, b) {
            console.log(a + b);
        }
        sum(2, 3);//5


        需求:定义一个函数,调用函数时传入price num
        计算总价。

        function total(price, num) {
            var all = price * num;
            document.write(all)
        }
        total(50, 2);
        函数的返回值:
        函数在调用后获得的数据
        在定义函数时,可以为函数指定一个返回值,函数的返回值可以是任意类型的数据
        在JS中使用return语句得到返回值并退出函数
        {return 表达式}

        function totalA(price, num) {
            var all = price * num;
            return all;
        }
        console.log(totalA(9999, 12));


        //需求:定义一个函数maxNum,求任意两数的最大值;
        function maxNum(a, b) {
            if (a > b) {
                console.log("最大值:" + a);
            } else {
                console.log("最大值:" + b);
            }
        }
        maxNum(6, 7)

2.函数内外变量的作用域

①变量

        //全局变量:在函数体外声明的变量或者是在函数体内省略var 关键词声明的变量
        var a = 10
        function demo() {
            console.log(a);//a为全局变量,在函数体内可以被访问
            c = 20
            console.log(c);//c是省略var关键词声明的变量,全局变量
        }
        demo()
        console.log(c);//可以在函数外访问到全局变量

        console.log(a);//a为全局变量,在函数体外可以被访问

        //局部变量:在函数体内利用声明的变量
        function demo1() {
            let b = 10;//函数内部定义的局部变量b,可以在函数内部被访问
        }
        demo1()
        // console.log(b);

        //块级变量:在ES6标准中,新增的let关键词声明的变量为块级变量
        //一个花括号{}为一个块级
        if (true) {
            let sex = '男' //let声明变量sex为块级变量
            console.log(sex); //块级变量sex可以在{}内部被访问
        }
        // console.log(sex); //块级变量sex不可在{}外部被访问 

        for (let i = 0; i < 5; i++) {
            console.log("循环内部" + i);
            console.log("循环外部" + i);//i is not defined
        }

②js三种作用域

        全局作用域:全局作用域:被全局变量所拥有:在{}外声明的变量

        局部作用域:被局部变量所拥有:在函数内定义的变量

        块级作用域:被块级变量所拥有:在分支语句或者循环大括号中定义的变量

        // 可以访问var声明的全局变量demo2,
        // 但是demo2目前没有赋值,为undefined
        console.log(demo2); //undefined
        var demo2 = 10;
        // let声明的全局变量
        //不允许在变量初始化前被访问
        console.log(test);// Cannot access 'test' before initializatio
        let test = 10
        function fun() {
            console.log(demo);//7console.log(test);//10
            fun()
            console.log(demo);//7console.log(test);//10
        }

③变量提升

        // 可以访问var声明的全局变量demo2,
        // 但是demo2目前没有赋值,为undefined
        console.log(demo2); //undefined
        var demo2 = 10;
        // let声明的全局变量
        //不允许在变量初始化前被访问
        console.log(test);// Cannot access 'test' before initializatio
        let test = 10
        function fun() {
            console.log(demo);//7console.log(test);//10
            fun()
            console.log(demo);//7console.log(test);//10
        }

3.函数进阶

  ①函数表达式

        //封装一个sun函数,在函数内可以求得变量num1和变量num2的和
        function sum(num1, num2) {
            var sum = num1 + num2;
            console.log(sum);
        }
        sum(1, 2);

        var ft = function sum1(num1, num2) {
            //在函数内部求得了一个和
            // 并将求得的和返回去
            //让函数外部可以拿到
            return num1 + num2;
        }
        console.log(ft(1, 3));

②匿名函数

        var fn = function (num1, num2) {
            console.log(num1 + num2);
        }
        fn(1, 3)

③箭头函数

        //删除function关键词
        //在参数和函数体中间放上 "=>"
        var fn1 = (num1, num2) => {
            console.log(num1 + num2);
        }
        fn1(1, 2)

        //当函数体只有一句话时可以省略{}
        var fn2 = (num1, num2) => console.log(num1 + num2);
        fn2(1, 2)

        //当函数只有一句代码,并且函数的执行结果,就是函数的返回值,可以省略return和{}
        var fn3 = (num1, num2) => num1 + num2;
        console.log(fn3(1, 2));

        //当参数只有一个时,可以省略函数外部的小括号
        var fn4 = num1 => num1 + num1;

4.回调函数

        // 函数fn作为参数传递给参数cal
        // 然后在函数cal中调用函数fn
        // 此时 fn就是回调函数
        function cal(num1, num2, fn) {
            return fn(num1, num2)
        }
        console.log(cal(10, 20, function (a, b) {
            return a + b;
        }));
        console.log(cal(10, 20, function (a, b) {
            return a * b;
        }));

        console.log(cal(10, 20, function (a, b) {
            return a % b;
        }));

        在cal函数中设置了回调函数后
        可以根据调用时传递不同的函数参数 (相加函数,相乘函数)
        去实现不同的功能
        实现函数的定制化

5.定时器函数

        // setInterval()
        //"时间间隔"一刀,代码就会执行一次

        setInterval(function,time)
        setInterval(function () {
            console.log("该上课了");
        }, 1000)

        //setTimeout()
        //用来指某个函数或某段代码在多少毫秒以后执行
        setTimeout(function,time)
        setTimeout(function () {
            console.log("要抢票了");
        }, 3000)

        //定时器函数属于异步代码
        //setTimeout指定的代码,必须等同步代码执行完毕后执行
        console.log(1);
        setTimeout(function () {
            console.log(2);
        }, 0)
        console.log(3);
        // 132

6.函数嵌套与作用域

        var i = 10
        function fn() {
            var i = 20;
            function fn1() {
                function fn2() {
                    console.log(i);
                }
                fn2()
            }
            fn1
        }
        fn1()

        // 变量访问原则:就近
        // 当在一个作用域中访问变量时,首先看当前作用域是否声明
        // 如果有则访问,没有则往上级作用域访问
        // 知道达到顶端作用域,如果还没有找到,则程序报错

7.闭包函数

        // 闭包(close): 闭包是一种代码形式,内部函数访问外部函数的局部变量

        // 举例:js函数a中有一个函数b,b访问了a里面定义的局部变量,此时就产生了闭包
        // 变量所在的函数就是闭包函数,在这里,a就是闭包函数

        // 外部函数
        function outer() {
            // 外部函数定义的局部变量
            let n = 10;
            // 内部函数
            function inner() {
                // 内部函数要访问外部函数定义的局部变量
                console.log(n);
            }
            inner()
        }
        outer()

        // 闭包的作用:解决变量污染问题,让变量被函数保护起来

        // let count = 0; setInterval(function () {
        //     console.log(count++);
        // }, 1000)
        // 在这段代码中,count是一个很常用的变量名,
        //     为了避免和其他位置的代码起冲突,可以使用一个函数将上面的代码包裹起来。

        function fn() {
            let count = 0;
            setInterval(function () {
                console.log(count++);
            }, 1000)
        }
        // 内部函数setInterval 访问外部函数fn 定义的局部变量count

        function fn() {
            let count = 0;
            function add() {
                console.log(count++);
            }
            console.log(add, count);
        }
        // 内部函数add访问外部函数fn定义的局部变量count。

8.网页计算器

<body>
    <p>整数1: <input type="text" id="num1"></p>
    <p>整数2: <input type="text" id="num2"></p>

    <p>
        <input type="button" value="相加" onclick="cal(add)">
        <input type="button" value="相减" onclick="cal(sub)">
        <input type="button" value="相乘" onclick="cal(mul)">
        <input type="button" value="相除" onclick="cal(div)">
    </p>
    <p>结果: <input type="text" id="result"></p>
</body>

<script>
    function add(num1, num2) {
        return num1 + num2;
    }
    function sub(num1, num2) {
        return num1 - num2
    }
    function mul(num1, num2) {
        return num1 * num2;
    }
    function div(num1, num2) {
        if (num2 === 0) {
            alert("除数不能为0")
            return "";
        }
        return num1 / num2;
    }

    // 在cal函数中需要传输一个回调函数
    function cal(func) {
        // 通过id "num1"得到HTMl中名字叫 "num1"的输入框的值。
        var nun1 = parseInt(document.getElementById("num1").value)
        var nun2 = parseInt(document.getElementById("num2").value)
        var result = document.getElementById("result")
        result.value = func(num1, num2)
    }

9.递归函数

        // 递归函数是一个函数间接或直接调用自身

        // function func() {
        //     console.log(1);
        //     func()
        // }

        // 需求:设置函数getSum()
        function getSum(n) {
            var sum = 0;
            for (var i = n; i >= 0; i--) {
                sum += i;
            }
            console.log(sum);
        }
        getSum(5)

        //递归写法
        function getSum1(n) {
            if (n == 1) {
                return 1;
            }
            //当前数组+比自己数字小1的数字
            return n + getSum1(n - 1)
        }
        console.log(getSum(5));
      function getmul(n) {
            if (n == 1) {
                return 1;
            }
            return n * getmul(n - 1)
        }
        console.log(getmul(5));

        function getmul1(n) {
            var mul = 1;
            for (var n; n > 0; n--) {
                mul *= n;
            }
            console.log(mul);
        }
        getmul1(5)


        function getvalue(n) {
            var arr = [1, 1]
            for (var i = 2; i < n; i++) {
                //比如下标i=6(下标为6)的数是8+5(下标为5)
                //i是下标,arr[i]对应的是数组值
                arr[i] = arr[i - 1] + arr[i - 2]
            }
            console.log(arr);
            return arr[arr.length - 1]
        }
        console.log(getvalue(10));


        function fbnq2(n) {
            if (n === 1 || n === 2) {
                return 1
            }
            return fbnq(n - 1) + fbnq(n - 2)
        }
        console.log(fbnq2(3));

        // n=10(需要知道在数组中第4个数是多少)
        // getValue1(4)= getValue1(3)+ getValue1(2)
        // getValue1(4)= getValue1(2)+ getValue1(1)+ 1
        // getValue1(4)=1+1+1=3

第五章 对象

1.介绍对象

        //1. 对象是什么:对象是一种复杂数据类型
        //(复杂数据类型的内容存储在堆内存中,地址存在栈内存中)
        //2. 对象作用:以键值的形式存储多个数据


        // 1.使用简单数据类型
        let name = '张三'
        let age = 38;
        let sex = '男'
        // 好处 : 阅读性高,
        // 弊端 : 冗余

        //2. 数组
        let peopel = ['张三', '38', '男']
        // 好处:一个变量可以储存多个数据
        // 弊端:阅读性不高

        //3.对象
        let obj = {
            name: "张三",
            age: 30,
            sex: '男'
        }
        console.log(obj);

        // 3.对象查询
        console.log(obj);
        console.log(obj.age);
        console.log(obj.sex);

        // 4.对象新增
        obj.bf="李四"
        console.log(obj);

        // 5.对象修改
        obj.bf = "王五"
        console.log(obj);

        // 对于对象的属性:如果有这个属性是修改属性值,没有属性是新增属性值

        3.4 对象删除
 
        delete obj.age
        console.log(obj);
      
        3.5 对象遍历
          遍历数组: for (let i=0; i<arr.lenght; i++){}
          遍历对象: for-in循环: for (let key in 对象名){对象名[key]}
          let score ={
            math:99,
            history:80,
            geology:70,
            english:60
         }
 
         for(let key in  score){
            console.log(key); 打印属性名
            console.log(score[key]); 打印属性值
         }

2.Math对象

        // 1.内置对象:由JS作者提前编写好的对象,里面存储了一些属性方法。直接使用即可
        // 2:Math数学对象,DATE日期对象

        // 计算半径为5 圆的周长;
        const π = 3.14
        const r = 5;
        const C = 2 * π * r
        console.log(C);


        // 1. 圆周率 Math.PI
        console.log(Math.PI);
        const c = 2 * Math.PI * r
        console.log(c);

        // 2. 绝对值 Math.abs()
        console.log(Math.abs(-3.5));

        // 3. 找最小最大值  Math.max/min()
        console.log(Math.min(1, 9, 5, 45, 4, 5));//1
        console.log(Math.max(1, 9, 5, 45, 4, 5));//45

        // 4. 幂运算 Math.pow (x,y) 求x的y次方
        console.log(2, 10);//1024

        // 5. 四舍五入 Math.round()
        console.log(Math.round(3.5));//4
        console.log(Math.round(-3.5));//-3

        // 6. 向上取整 Math.ceil()
        console.log(Math.ceil(3.1));//4
        console.log(Math.ceil(-3.5));//-3

        // 7. 向下取证 Math.floor()
        console.log(Math.floor(-1.8));// -2

        // 8. 生成一个0~1之间的随机小数 Math.random()
        console.log(Math.random());
        // 生成一个0-100之间的随机整数
        console.log(Math.round(100 * Math.random()));

3.Math对象案例

    <!-- 需求:点击按钮抽奖
    抽到数字1,是一等奖
    2,3,是二等奖
    4-7,是三等奖
    8-10,是谢谢惠顾 -->
    <input type="button" value="抽奖" onclick="btn()" id="btn">
    <script>
        // 当点击btn按钮时,会触发function函数
        var btn = function () {
            var rand = Math.random()
            // 设置抽奖范围/人数
            var total = 100;
            // 设置抽奖等级
            var level = 0;
            // 设置抽奖结果
            var bouns = 0;

            // 抽奖过程
            // 将number转化为一个0-100的整数
            number = Math.round(Math.random() * 100)

            // 抽奖结果
            if (number == 1) {
                level = 1
            } else if (number <= 3 || number >= 2) {
                level = 2
            } else if (number <= 7 || number >= 4) {
                level = 3
            }

            if (level <= 7) {
                alert(" 恭喜你获得了" + level + "等奖")
            } else { alert("谢谢惠顾") }

        } 

4.Date对象

        // 时间戳:从1970年1月1日0分0秒到现在的毫秒数
        //以下三种写法都会得到时间戳
        console.log(Date.now());
        console.log(+new Date);
        console.log(new Date().getTime());

        // 年份
        console.log(new Date().getFullYear());
        // 月份
        console.log(new Date().getMonth());//0-11
        // 日期
        console.log(new Date().getDate());//1-31
        // 星期
        console.log(new Date().getDay());//0-6 周日是0
        // 小时
        console.log(new Date().getHours());
        // 分钟
        console.log(new Date().getMinutes());

        // 练习:显示今天是2024年五月二十二日,星期三
        console.log("今天是" + new Date().getFullYear() + "年"
            + (new Date().getMonth() + 1) + "月" + new Date().getDate() + "日 星期" + new Date().getDay());

        // 练习:显示“1998年8月1日是我出生的日子”
        //在页面中显示1998年8月1日是我出生的日子
        //获取内置Date对象
        var date = new Date();

        //设置年份
        date.setFullYear(2004)
        date.setMonth(12)
        date.setDate(6)

        //获取年份
        var year = date.getUTCFullYear() - 1
        var month = date.getMonth() + 12
        var date = date.getDate()

        //打印年份
        console.log(year);
        console.log(month);
        console.log(date);
        alert(year + "年" + month + "月" + date + "日" + "是我的生日")

        //练习:页面显示生日倒计时
        //参数time是下一次生日的时间
        function count(time) {
            //得到当前时间时间戳
            var nowTime = new Date()
            //得到生日时的时间戳
            var overTime = new Date(time)
            //即将过生日的时间减去现在的时间得到生日倒计时
            //除1000得到秒数
            var times = (overTime - nowTime) / 1000
            console.log(times);

            //天数
            var day = parseInt(times / 60 / 60 / 24)
            console.log(day);

            //小时
            var hours = (times / 60 / 60 % 24)
            console.log(hours);

            // 分钟
            var mins = parseInt(times / 600 % 60)
            console.log(mins);

            // 秒数
            var sec = parseInt(times % 60)
            console.log(sec);

            alert("生日倒计时:" + day + "天" + Math.floor(hours) + "小时" + mins + "分钟" + sec + "秒")
        }
        console.log(count("2024-12-6 00:00:00"));

        prompt("请以 xxxx-xx-xx xx:xx:xx的形式输入年-月-日 小时:分钟:秒数")
        var birthday = prompt();

5.Array对象

    <script>
        var course = ["web", "java"]

        //push()在数组末尾添加一个元素
        course.push("javaScript")
        console.log(course); //["web","java","JavaScript"]

        //unshift() 在数组开头添加一个元素
        course.unshift("计算机基础")
        console.log(course); //['计算机基础', 'web', 'java', 'javaScript']

        //pop()删除数组中最后一个元素
        course.pop()
        console.log(course); //['计算机基础', 'web', 'java']

        // shift()删除数组第一个元素
        course.shift()
        console.log(course);//['web','java']

        // splice [start,deleteCount]
        var arr = [1, 2, 3, 4, 5, 6, 7, 8]
        arr.splice(3, 2)//从下标为三开始,删掉后面两个数
        console.log(arr);//[1,2,3,6,7,8]
        // deleteCount = 0;
        arr.splice(4, 0, 99, 88, 77) //从下标为4的数字开始,往后添加一些元素
        console.log(arr);

        //reverse():颠倒数组中元素的索引
        var arr1 = [1, 2, 3, 4, 5, 6, 7]
        arr1.reverse()
        console.log(arr1); //[7, 6, 5, 4, 3, 2, 1]


        //sort
        //升序排序
        var arr2 = [19, 45, 29, 0, 18, 73]
        arr2.sort(function (a, b) {
            return a - b
        })
        console.log(arr2); //[0, 18, 19, 29, 45, 73]
        //降序排序
        var arr3 = [19, 45, 29, 0, 18, 73]
        arr3.sort(function (a, b) {
            return b - a
        })
        console.log(arr3); //[73, 45, 29, 19, 18, 0]

        //获取元素索引的方法
        //indexOf(element) 返回指定元素在数组中第一次出现的索引,不存在则返回-1
        //lastIndexOf(element) 返回指定元素在数组中最后一次出现的索引,不存在则返回-1
        var color = ["green", "pink", "red", "pink", "yellow", "red"]
        console.log(color.indexOf("red")); //2
        console.log(color.indexOf("white")); //-2
        console.log(color.lastIndexOf("red"));  //5

        //将数组转化为字符串
        //toString() 将数组转化为字符串,用逗号分隔数组中的每个元素
        //join() 将数组中的所有元素连接成一个字符串。默认用逗号分隔,可指定分隔符
        console.log(color); //['green', 'pink', 'red', 'pink', 'yellow', 'red']
        console.log(color.toString()); //green,pink,red,pink,yellow,red
        console.log(color.join()); //green,pink,red,pink,yellow,red
        console.log(color.join("")); // greenpinkredpinkyellowred
        console.log(color.join("_")); //green_pink_red_pink_yellow_red

        //数组类型检测
        var obj = { name: '张三' }
        console.log(Array.isArray(arr));//true
        console.log(Array.isArray(obj));//false
    </script>

6.String对象

 <script>
        //创建字符串对象
        var str = new String("apple")
        console.log(str); // {'apple'}

        //访问字符串长度
        console.log(str.length); //5
        //数据类型检测
        console.log(typeof (str)); //object
        var str1 = "banana"
        console.log(typeof (str1)); //string
        //根据字符串返回索引
        //indexOf() 返回字符串中首次出现的索引,没有则返回-1
        //lastIndexOf(element) 返回字符串中最后一次出现的索引,没有则返回-1
        var str = "helloword"
        console.log(str.indexOf("o")); //4
        console.log(str.lastIndexOf("o")); //6
        //根据索引返回字符串
        //chatAt
        console.log(str.charAt(7)); //'r'

        //字符串截取
        //slice (start)
        console.log(str.slice(5)); //"word"
        //slice(start,end) 从start的下标截取到end的下标
        console.log(str.slice(1, 4));  //ell""
        console.log(str); //helloword  截取不会改变原数组

        //字符串连接
        //concat()
        var str1 = "hello"
        var str2 = ",word"
        console.log(str.concat(str2)); //helloword,word

        //大小写转换
        //toUpperCase 转化为大写
        //tolowerCase 转化为小写
        console.log(str1.toLocaleUpperCase());

        //替换
        //replace(str1,str2)
        console.log(str);  //helloworld
        console.log(str.replace("world", "JS")); //helloJS

        //字符串分隔 (将字符串转化为数据)
        //split(分隔符)
        console.log(str.split("")); //['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
        console.log(str.split());  //['helloworld']
        console.log(str.split("o")); // ['hell', 'w', 'rld']
    </script>

;