JavaScript核心基础总结笔记

2 篇文章 0 订阅
2 篇文章 0 订阅

JavaScript

在这里插入图片描述

前言:大家好、我是小编达闻西,很高兴又和大家见面了。上篇文章我总结了一下html,css的常用基础知识。这次我又重新的把JavaScript的相关知识点给总结了一下。发现js的东西真的好多好多,我总结了差不多有一周,其中还有一些demo和知识点。不过我觉得学习不仅仅需要一路向前、还应该对学习过的知识进行总结,温故知新。希望我的这篇文章能帮助到你,如有不足请指正。

image-20220808160135873

文章目录

一、JS介绍

ECMAScript是什么?

ECMAScript浏览器脚本语言标准
ECMAScript <=>javascript

javascrip能做什么?

  • 浏览器客户端开发(前端开发) 核心
  • 服务器开发 (java)
  • 桌面程序开发

javascript的组成

ECMAScript 定义基础语法

  • BOM 浏览器对象模型, 操作浏览器窗口能力
  • DOM 文档对象模型, 操作html文档能力

javascript书写位置

1.内嵌式(script标签中)推荐
2.行内式
3.外链式

javascript的特点

  1. 基于原型的面向对象,JavaScript是一门面向对象的语言
  2. 严格区分大小写

JavaScript的注释

  • 单行注释:// 注释内容
  • 多行注释:/* 注释内容 */

二、变量

2.1 js的变量(重点)

  • 变量指的就是一个数据的容器

  • 变量是计算机内存种储存数据的标识符、根据变量名称可以获取到内存中的存储的数据

  • 变量的本质是内存中一个存储单元

  • 语法:var 变量名 = 值

  • 取名规范:

    • 不能数字开头、不能使用中文汉字命名
    • 不能是关键字、保留字
    • 不能出现空格
    • 组成:数字、字母、下划线_、美元符号$
    // 定义一个变量
    var num;
    
    // 给一个变量赋值
    num = 100;
    
    // 定义一个变量的同时给其赋值
    var num2 = 200;
    
    • 注意:
      • 一个变量名只能存储一个值
      • 当第二次赋值的时候,第一次的值就会被覆盖
      • 变量名称区分大小写

2.2 js的数据结构(重点)

概念解释:是指我们存储在内存中的数据的类型

基本数据类型

  1. 数值类型(number)
    • 一切数字都是数值类型(二进制、十进制、十六进制等)
    • NAN(not a number),一个非数字
  2. 字符串类型(string)
    • 使用引号包裹的内容(双引号、单引号均可)
  3. 布尔类型(boolean)
    • true(真)
    • false(假)
    • 只有两个值
  4. null类型(null)
    • null(空)
    • 只有一个值
  5. undefined类型(undefined)
    • undefined(没有值)
    • 只有一个值

复杂数据类型

  1. 对象类型(object)
  2. 函数类型(function)

判断数据类型(typeof)

  • 使用typeof关键进行类型判断

  • 基础用法

    // 第一种使用方式
    var n1 = 100;
    console.log(typeof n1);
    
    // 第二种使用方式
    var s1 = 'abcdefg';
    console.log(typeof(s1));
    
    • 判断变量是否为数值(isNaN)

    • isNaN: is not a number

    • 是数字:false

    • 非数字:true

      // 如果变量是一个数字
      var n1 = 100;
      console.log(isNaN(n1)); //=> false
      
      // 如果变量不是一个数字
      var s1 = 'Jack'
      console.log(isNaN(s1)); //=> true
      

2.3 js的数据类型转换

概念:数据类型之间的转换,如数字传字符串

转为数值的方法

  1. Number(变量)
    • 概念:将值强制转换为数值类型
    • 可以转换小数、会保留小数
    • 可以转换布尔值
    • NaN是Number类型,但不是数字
    • 不可转换的值会返回NaN
  2. parseInt(变量)
    • 概念:从第一位检查、数字就转换、不是就返回
    • 用法:对小数进行取整(保留整数)
    • 注意:如果开头就不是数值、直接返回NaN;
  3. parseFloat(变量)
    • 概念:从第一位检查、数字就转换、知道一次小数点然后再返回
    • 用法:保留小数点的时候
    • 注意:如果开头就不是数值、直接返回NaN;
  4. 除了加法(+)以外的数学运算
    • 运算符两边不管是字符串还是数值 必须是数字才行
    • 如两边任意一边不是数字:返回NaN
    • +法不能用,会被当为连接符号

转换成字符串

  1. toString()
    • 概念:将值转换成为字符类型
    • 注意:undefined和null 不可进行转换
  2. String(变量)
    • 所有类型都可以进行转换
  3. 使用加法+运算
    • 第一种用法;两边都是数值的时候、进行+法运算
    • 第二种用法:+的任意一边是字符串、就会进行字符串拼接

转换成布尔类型

  1. Boolean(变量)
    • 在 js 中,只有 ''0nullundefinedNaN,这些是 false,其余都是 true

2.4 js的运算符

数学运算符

  1. +

    • 只有符号两边都是数字的时候才会进行加法运算
    • 只要符号任意一边是字符串类型,就会进行字符串拼接
  2. -

    • 会执行减法运算

    • 会自动把两边都转换成数字进行运算

  3. *

    • 会执行乘法运算
    • 会自动把两边都转换成数字进行运算
  4. /

    • 会执行除法运算
    • 会自动把两边都转换成数字进行运算
  5. %

    • 会执行取余运算
    • 会自动把两边都转换成数字进行运算

赋值运算符

  1. =

    • 就是把 = 右边的赋值给等号左边的变量名
    • var num = 100
    • 就是把 100 赋值给 num 变量
    • 那么 num 变量的值就是 100
  2. +=

    var a = 10;
    a += 10;
    console.log(a); //=> 20
    
    • a += 10 等价于 a = a + 10
  3. -=

    var a = 10;
    a -= 10;
    console.log(a); //=> 0
    
    • a -= 10 等价于 a = a - 10
  4. *=

    var a = 10;
    a *= 10;
    console.log(a); //=> 100
    
    • a *= 10 等价于 a = a * 10
  5. /+

    var a = 10;
    a /= 10;
    console.log(a); //=> 1
    
    • a /= 10 等价于 a = a / 10
  6. %=

    var a = 10;
    a %= 10;
    console.log(a); //=> 0
    
    • a %= 10 等价于 a = a % 10

比较运算符

  1. ==
    • 比较符号两边的值是否相等,不管数据类型
    • 1 == '1'
    • 两个的值是一样的,所以得到 true
  2. ===
    • 比较符号两边的值和数据类型是否都相等
    • 1 === '1'
    • 两个值虽然一样,但是因为数据类型不一样,所以得到 false
  3. !=
    • 比较符号两边的值是否不等
    • 1 != '1'
    • 因为两边的值是相等的,所以比较他们不等的时候得到 false
  4. !==
    • 比较符号两边的数据类型和值是否不等
    • 1 !== '1'
    • 因为两边的数据类型确实不一样,所以得到 true
  5. >=
    • 比较左边的值是否 大于或等于 右边的值
    • 1 >= 1 true
    • 1 >= 0 true
    • 1 >= 2 false
  6. <=
    • 比较左边的值是否 小于或等于 右边的值
    • 1 <= 2 true
    • 1 <= 1 true
    • 1 <= 0 false
  7. >
    • 比较左边的值是否 大于 右边的值
    • 1 > 0 true
    • 1 > 1 false
    • 1 > 2 false
  8. <
    • 比较左边的值是否 小于 右边的值
    • 1 < 2 true
    • 1 < 1 false
    • 1 < 0 false

逻辑运算符

  1. &&
    • 进行 且 的运算
    • 符号左边必须为 true 并且右边也是 true,才会返回 true
    • 只要有一边不是 true,那么就会返回 false
    • true && true true
    • true && false false
    • false && true false
    • false && false false
  2. ||
    • 进行 或 的运算
    • 符号的左边为 true 或者右边为 true,都会返回 true
    • 只有两边都是 false 的时候才会返回 false
    • true || true true
    • true || false true
    • false || true true
    • false || false false
  3. !
    • 进行 取反 运算
    • 本身是 true 的,会变成 false
    • 本身是 false 的,会变成 true
    • !true false
    • !false true

自增自减运算符(一元运算符)

解题思路:(全款||贷款)

  • ++在前的指是返回给a变量自身立马变现

  • 在后的++指的是,现在的值是多少先返回。贷款学习、后面再给钱

  • 引申例子:

        <script>
            var k = -2;
            alert(++k + k++ + ++k + k)
            // 总解析:-1 + -1 = -2   k=0    + 1 +1  k=0
            // 第一步解析:
            console.log(++k + k++);  //输出:-2
            console.log(k);         //输出:0
    
            // 第二步解析
            console.log(++k+k);     //输出:1 +1 = 2
            console.log(k);         //输出:1
        </script>
    
  1. ++

    • 进行自增运算

    • 分成两种,前置++后置++

    • 前置++,会先把值自动 +1,在返回

      var a = 10;
      console.log(++a);
      // 会返回 11,并且把 a 的值变成 11
      
    • 后置++,会先把值返回,在自动+1

      var a = 10;
      console.log(a++);
      // 会返回 10,然后把 a 的值变成 11
      
  2. --

    • 进行自减运算
    • 分成两种,前置–后置–
    • ++ 运算符道理一样

三、逻辑分支语句

3.1 if条件分支结构

if语句

  • 通过一个if语句来决定是否执行

  • 语法:if(条件){要执行的代码}

    // 条件为 true 的时候执行 {} 里面的代码
    if (true) {
      alert('因为条件是 true,我会执行')
    }
    
    // 条件为 false 的时候不执行 {} 里面的代码
    if (false) {
    	alert('因为条件是 false,我不会执行')    
    }
    
  • 引申例题:求n个数的最大值

  • 解题思路:

    1. 先定义一个max变量接受最大值
    2. 再假设一个数为最大值、并赋值给max
    3. 再使用if语句接着判断之后的数字
    4. 直到比完最后一个数字,max就为最大数字了
                // 1. 求35和46,68三个数最大值?(两个数不相等)
                var m = 75
                var n = 86
                var x = 68
    
                var max = m //假设第一个数据是最大值
                if (n > max) {
                    max = n
                }
                if (x > max) {
                    max = x
                }
                console.log('最大值是', max)
    

if else语句

  • 语法: if (条件) { 条件为 true 的时候执行 } else { 条件为 false 的时候执行 }

  • 注意:两个{}内的代码一定会有一个执行

    // 条件为 true 的时候,会执行 if 后面的 {} 
    if (true) {
      alert('因为条件是 true,我会执行')
    } else {
      alert('因为条件是 true,我不会执行')
    }
    
    // 条件为 false 的时候,会执行 else 后面的 {}
    if (false) {
      alert('因为条件为 false,我不会执行')
    } else {
      alert('因为条件为 false,我会执行')
    }
    
  • 引申例题:求是否是闰年

  • 解题思路:闰年:(能被4整除&&不能被100整除)||(可以被400整除的年份)

     var year = 2024 //年份
            if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
                console.log(year, '是闰年');
            }else{
                console.log(year, '不是闰年');
            }
    

if else if …语句

  • 语法:if (条件1) { 条件1为 true 的时候执行 } else if (条件2) { 条件2为 true 的时候执行 }

  • 多个 {} ,只会有一个被执行,一旦有一个条件为 true 了,后面的就不在判断了

    // 第一个条件为 true,第二个条件为 false,最终会打印 “我是代码段1”
    if (true) {
      alert('我是代码段1')
    } else if (false) {
    	alert('我是代码段2')           
    }
    
    // 第一个条件为 true,第二个条件为 true,最终会打印 “我是代码段1”
    // 因为只要前面有一个条件满足了,就不会继续判断了
    if (true) {
      alert('我是代码段1')
    } else if (true) {
      alert('我是代码段2')
    }
    
    // 第一个条件为 false,第二个条件为 true,最终会打印 “我是代码段2”
    // 只有前一个条件为 false 的时候才会继续向后判断
    if (false) {
      alert('我是代码段1')
    } else if (true) {
      alert('我是代码段2')
    }
    
    // 第一个条件为 false,第二个条件为 false,最终什么也不会发生
    // 因为当所有条件都为 false 的时候,两个 {} 里面的代码都不会执行
    if (false) {
      alert('我是代码段1')
    } else if (false) {
      alert('我是代码段2')
    }
    
  • 引申例题:求分数

            var score = 99 //分数
    
            if (score >= 90 && score <= 100) {
                console.log('A级');
            } else if (score >= 80 && score <= 89) {
                console.log('B级');
            } else if (score >= 70 && score <= 79) {
                console.log('C级');
            } else if (score >= 60 && score <= 69) {
                console.log('D级');
            }
    

if else if … else语句

  • 和之前的 if else if ... 基本一致,只不过是在所有条件都不满足的时候,执行最后 else 后面的 {}

    // 第一个条件为 false,第二个条件为 false,最终会打印 “我是代码段3”
    // 只有前面所有的条件都不满足的时候会执行 else 后面的 {} 里面的代码
    // 只要前面有一个条件满足了,那么后面的就都不会执行了
    if (false) {
      alert('我是代码段1')
    } else if (false) {
      alert('我是代码段2')
    } else {
      alert('我是代码段3')
    }
    
  • 引申例题:求标准体重

           	    var height = 180 //测试者身高
                var weight = 150 //测试者体重
                var biaozWeight = (height - 108) * 2 //标准体重
    
                if(biaozWeight-10 > weight){
                    console.log('偏轻');
                }else if(biaozWeight + 10 < weight){
                    console.log('偏重');
                }else{
                    console.log('正常');
                }
    

3.2 SWITCH 条件分支结构

  • 对于一个变量的判断

  • 语法:

    switch (要判断的变量) {
      case 情况1:
        情况1要执行的代码
        break
      case 情况2:
        情况2要执行的代码
        break
      case 情况3:
        情况3要执行的代码
        break
      default:
        上述情况都不满足的时候执行的代码
    }
    
  • 引申例题:求任意一年的月份的天数

    • 通过switch穿透语句实现多语句重复的复写
    • 再写一个if判断语句
     var year = 2024 //年份
                var month = 1 //月份
                var day = 0 //天数
                switch (month) {
                    case 1:
                    case 3:
                    case 5:
                    case 7:
                    case 8:
                    case 10:
                    case 12:
                        day = 31
                        break
                    case 4:
                    case 6:
                    case 9:
                    case 11:
                        day = 30
                        break
                    case 2:
                        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                            day = 29
                        } else {
                            day = 28
                        }
                }
                var str = year + '年' + month + '月天数是' + day + '天'
                console.log(str);
    

3.3 三元运算(扩展)

  • 三元运算,就是用 两个符号 组成一个语句

  • 三元运算只是对 if else 语句的一个简写形式

  • 语法: 条件 ? 条件为 true 的时候执行 : 条件为 false 的时候执行

    var age = 18;
    age >= 18 ? alert('已经成年') : alert('没有成年')
    

3.4 while循环

  • 语法:while(条件){满足条件就执行}

    • while(1){}死循环
  • 注意:如果没有自身改变、那么就会一直循环不停(死循环)

    // 1. 初始化条件
    var num = 0;
    // 2. 条件判断
    while (num < 10) {
      // 3. 要执行的代码
      console.log('当前的 num 的值是 ' + num)
      // 4. 自身改变
      num = num + 1
    }
    

3.5 do while循环

  • 概念:不管条件、先执行一回,然后再开始进行进行条件判断

  • 语法:do{要执行的代码} while(条件)

    // 下面这个代码,条件一开始就不满足,但是依旧会执行一次 do 后面 {} 内部的代码
    var num = 10
    do {
      console.log('我执行了一次')
      num = num + 1
    } while (num < 10)
    

3.6 for循环

  • 语法:for (var i = 0; i < 10; i++) { 要执行的代码 }

  • 大于小于:i的值现在的值 跟最后的值进行比较

    // 把初始化,条件判断,自身改变,写在了一起
    for (var i = 1; i <= 10; i++) {
      // 这里写的是要执行的代码
      console.log(i)
    }
    
    // 控制台会依次输出 1 ~ 10 
    
  • 引申例题:累加求和

  • 思路:

    • 打印出1-10的所有数字
    • 将所有的偶数变为负数
    • 将n的值传给一个临时变量
    • 累加求和
    		   var temp = 0;
                var sum = 0;
                for(var n = 1; n <= 10;n++){
                    temp = n;
                    if(temp % 2 == 0){
                        temp = -n;
                    }
                    sum = sum + temp;
                }
                console.log(sum);
    

3.7 终止循环break

  • 只要语句中有break、提前就终止循环

  • 例子:五个包子,吃到第3个包子就不吃了、出去吃挂面了

    for (var i = 1; i <= 5; i++) {
      // 没循环一次,吃一个包子
      console.log('我吃了一个包子')
      // 当 i 的值为 3 的时候,条件为 true,执行 {} 里面的代码终止循环
      // 循环就不会继续向下执行了,也就没有 4 和 5 了
      if (i === 3) {
        break
      }
    }
    
  • 引申例题:打印100以内可以被4整除的前四个数字

  • 思路:

    1. 打印100以内的所有数
    2. 100以内能被4整除的数
    3. 打印前四个
    4. 在写一个计数器,写在满足的条件中,可以整除就+1
    5. 写一个语句判断需要多少个数字
    6. for语句和if语句都是需要 条件为真的时候才执行
      1. for语句是要知道现在 n <= 100 现在必须满足条件、如不满足条件就无法执行
      2. if语句 是要知道最后 count >= 4 现在不能满足条件、满足条件就执行
javascript
 var count = 0;  //定义一个计数器
            for(var n = 1; n <= 100; n++){
                if(n % 4 == 0){
                    count++;
                    console.log(n);  //输出结果:4 8 12 16
                }
                if(count >= 4){
                    
                    break;
                }
            }

3.8 终止本次循环continue

  • 在循环、把循环本次的本次跳过去、继续执行后续的循环

  • 例子:五个包子,吃到第三个包子、发现是石头做的、直接丢掉、吃第四个

    for (var i = 1; i <= 5; i++) {
      // 当 i 的值为 3 的时候,执行 {} 里面的代码
      // {} 里面有 continue,那么本次循环后面的代码就都不执行了
      // 自动算作 i 为 3 的这一次结束了,去继续执行 i = 4 的那次循环了
      if (i === 3) {
        console.log('这个是第三个包子,掉地下了,我不吃了')
        continue
      }
      console.log('我吃了一个包子')
    }
    

3.9 双重for循环

  • 概念:外层循环循环一次,内层就要循环完

  • 打印九九乘法:外层循环打印行、内层循环打印列。

    <script>
        /*
                1x1=1 
                2x1=2 2x2=4 
                3x1=3 3x2=6 3x3=9 
                4x1=4 4x2=8 4x3=12 4x4=16 
                5x1=5 5x2=10 5x3=15 5x4=20 5x5=25 
                6x1=6 6x2=12 6x3=18 6x4=24 6x5=30 6x6=36 
                7x1=7 7x2=14 7x3=21 7x4=28 7x5=35 7x6=42 7x7=49 
                8x1=8 8x2=16 8x3=24 8x4=32 8x5=40 8x6=48 8x7=56 8x8=64 
                9x1=9 9x2=18 9x3=27 9x4=36 9x5=45 9x6=54 9x7=63 9x8=72 9x9=81 
            */
    
    
    
        // 思路:
        //     先打印他们的行数(使用外层循环)
        //     再打印里面的内容(使用内层循环)
        for(var i = 1;i <= 9;i++){
            for(var j = 1;j <= i;j++){
                document.write(i+"*"+j+'='+i*j+'&emsp;')
            }
            document.write('<br>')
        }
    </script>
    
  • 引申例题:打印菱形:通过分解将三角形分为空格和符号两种打印

    • 打印上半三角形

      • 打印出一个三角形(个数1、3、5、7、9)
      • 打印空格(个数5、4、3、2、1)
      • 在一个大循环中、写一个循环完成空格 (i >= n)
      • 再在大循环中、再写一个循环完成’‘ (j <= 2n -1)
    • 打印下半三角形

      • 打印出一个三角形(个数9、7、5、3、1)
      • 打印出空格(个数1、2、3、4、5)
      • 再一个大循环中、写一个循环完成空格(i <= n)
      • 再再大循环中、再写一个循环完成“”(j >= 2n-1)
     *
    ***
   *****
  *******
 *********
 *********
  *******
   *****
    ***
     *          

        for(var n = 1; n <= 5;n++){
                for(var i = 5; i >= n; i--){ 
                    document.write("&nbsp;")
                }
                for(var j = 1;j <= 2*n-1;j++){
                    document.write('*')
                }
                document.write('<br>')
            }

            for(var n = 1; n <= 5;n++){
                for(var i = 1;i <= n; i++){
                    document.write('&nbsp;')
                }
                for(var j = 9; j >= 2*n-1;j--){
                    document.write('*')
                }
                document.write('<br>')
            }

四、函数

4.1 函数基本介绍

  • 预解析:会将变量声明域声明函数再对应的全域或者局部域提前

  • 声明式提前、赋值式不会提前

  • 概念:将任意代码封装到一起、需要用的时候进行调用执行

  • 函数的两种定义方式

    • 声明式

      function fn(){
          
      }
      
    • 赋值式

      var fn = function(){
      
      }
      
  • 语法:

    • 定义函数:

      function 函数名(){
          函数体(封装的代码)
      }
      
    • 函数调用:

      函数名();
      

4.2 函数的参数

  • 形参:

    • 就是在函数内可以使用的变量、在函数外不能使用的变量
    • 形参的值是由外面的实参决定的
  • 实参:

    • 在函数调用的时候给形参赋值的
    • 多个参数的时候、顺序对应的
  • 函数参数的默认值

    • 当函数没有给实参的时候、函数有一个默认的值

      function 函数名(形参1,形参2){
      	形参1= 形参1 || 默认值1
      	形参2= 形参2 || 默认值2
      	
      	函数体
      }
      
      函数名(实参1函数名()
      

4.3 函数返回值return

概念:其实就是给函数一个返回值和终断函数

中断函数:

  • 函数开始执行的时候、函数内部的代码就会从上到下的执行、直到代码全部执行完毕

  • return关键字就是可以在函数中间的位置停掉、让后面的代码不再继续执行

    function fn(){
    	console.log(1);
    	console.log(2);
    	console.log(3);
    	
    	return
    	//写了return之后 后面的4 、5就不会执行了
    	console.log(4)
    	console.log(5)
    }
    

返回值:

  • return关键字就是可以给函数执行完毕一个结果
  • 函数内部使用return关键字可以把任何内容当作这个函数运行的结果

4.4 变量作用域

概念:一个变量可以生效的范围、变量不是在所有地方都可以使用的、而这个变量的范围就是作用域

全局作用域

  • 概念:最大的作用域、可以在任何地方使用、这个作用域会一直存在、知道页面就销毁了

  • 具体写法

    var num = 100
    

局部作用域

  • 概念:只有函数才能生成局部作用域、每一个函数都是一个局部作用域

  • 具体写法

    function fn(){
        var num = 100
    }
    

变量使用规则:访问规则

  • 首先在自己的作用域找、如果有就直接使用
  • 没有就去上级作用域查找、如果有就直接使用
  • 没有就去上级作用域查找、依次类推
  • 知道全局作用域没有这个变量、就会直接报错
  • 注意事项:作用域的查找机制只能向上找、不能向下找

变量使用规则:变量赋值规则

  • 先在自己的作用域查找、有就直接赋值
  • 没有就去上一级作用域内部查找、有就直接赋值
  • 直到全局作用域都没有、那么就会把这个变量定义为全局变量、再给它赋值

作用域链

  • 变量访问或赋值时先在自己的作用域查找
  • 如果没有找到就再一层一层的向上找、直到最外层全局作用域
  • 这种层层查找的关系叫做作用域

4.5 递归函数

  • 函数定义好之后必须要使用函数调用语句才会执行

  • 将函数的调用语句写在函数内部、调用自己的函数就称为递归函数

  • 注意:递归函数一旦执行、会循环往复、没有止尽。需要给递归函数设置一个结束条件、否则就是死递归。

  • 例题1:求1+2+3+4+5的总和

    • 思路:
      • 定义一个形参n,让n的一个值做为结束递归的条件
      • 结束递归条件 就用return 加上你赋予的值
      • 循环条件就设置为 return 函数(n-1)+n
            function dg(n){
                if(n == 1){
                    return 1
                }
                return dg(n-1) + n
            }
            var sum = dg(5)
            document.write(sum)
    
  • 例题2:求斐波拉切数列

    • 思路

      • 将第一位和第二位数作为结束条件,return的值为1
      • 现在这个数=前一个数+前前一个数
      • n=(n-1)+(n-2)
    •       function fb(n){
                    if(n == 1 || n ==2){
                        return 1
                    }
                    return fb(n-1) + fb(n - 2)
                }
        
                var sum = fb(7)
                document.write(sum)
      

4.6 arguments和自执行函数

arguments:

  1. 在函数内部自带的变量,表示所有实参的集合,是伪数组
function sum() {
var s = 0
console.log(arguments); 
/* 控制台
Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
0: 1
1: 2
2: 3
3: 4
4: 5
callee: ƒ sum()
length: 5
Symbol(Symbol.iterator): ƒ values()
[[Prototype]]: Object */

console.log(arguments.length); // 5
console.log(arguments[3]); //4
for (var i = 0; i <= arguments.length; i++) {
s += i;
}
return s
}
var getSum = sum(1, 2, 3, 4, 5)
console.log(getSum); //15

自执行函数

  • 概念:自行执行

    (function () {
    var num = 100
    console.log(num)
    })()
    

回调函数

一个函数作为另一个函数的参数、在另一个函数中被调用、这样的函数被成为回调函数。

处理异步请求的结果

image-20220720142432862

image-20220720142510817

五、数组

概念:

  1. 数组是一系列有序数据的集合
  2. 数据的集合、存储多个数

5.1 数组基础

  1. 创建数组:

    • 构造函数方式

      var arr = new Array()			//创建一个空数组
      var arr = new Array(1,2,3,4)	//数组存储1,2,3,4
      var arr = new Array(10)		   //创建一个可以存储10个元素的数组
      
    • 字面量方式

      var arr = []		//创建一个空数组
      var obg = {}		//创建一个空对象
      var arr = [1,2,3,4]	//数组存储1,2,3,4
      
  2. 数组的长度:

    • array.length:就是表示数组的长度、数组有多少个成员、length就是多少
    • 数组的索引:是从0开始的
  3. 遍历数组:

    • 数组的长度可以使用array.length:就是表示数组的长度

    • 利用for循环来实现一个遍历数组

      var arr = [1, 2, 3, 4, 5]
      
      for (var i = 0; i < arr.length; i++) {
          console.log(arr[i]); //依次输出1,2,3,4,5
      }
      
    • 例题引申:数组中最大的一个数

      • 定义max将数组的第一个array[0]赋值给max

      • 在通过循环,遍历比较所有数字

      • 输出max的值

        var score = [89, 78, 90, 99, 67, 59];
        var max = score[0]; 	//将数组第一个赋值给max
         for (var n = 0; n < score.length; n++) {
                        temp = score[n];	//将第n个数组的值返回给temp
                        if(max < temp){
                            max = temp;		//将数组值赋值给max
                        }
          }
          console.log("最大"+max);
        
    • 例题引申:数组中有几个目标数字

      • 创建一个计数器,去接收满足条件的值

      • 通过循环,遍历判断符合的值

      • 输出计数器的值

        var score = [89, 78, 90, 99, 67, 59];
        var bjg = 0;
         for (var n = 0; n < score.length; n++) {
                        temp = score[n];	//将第n个数组的值返回给temp
                        if(temp < 60){
                            bjg++;
                        }
          }
          console.log("不及格个数"+bjg);
        
  4. 堆和栈的存储区别

    1. image-20220714195736000
    2. 栈(基本):主要存储基本数据类型的内容
    3. 堆(复杂):主要存储复杂数据类型的内容
    4. 数据之间的比较
      1. 基本数据类型是值之间的比较
      2. 复杂数据类型是地址之间的比较

5.2 数组的常用方法

增:

  1. push: 在数组末尾追加一个元素

    • Array.push(4) :括号里面写添加的元素
    var arr = [1,2,3]
    
    //使用push在末尾追加一个元素
    arr.push(4)	//直接写元素值
    console.log(arr); //控制台输出结果:1234
    
  2. unshift: 在数组最前端添加一个元素

    • Array.unshift(4) :括号里面写添加的元素

      var arr = [1,2,3]
      
      //使用unshift在数组最前端添加一个元素
      arr.unshift(4)	//直接写元素值
      console.log(arr); //控制台输出结果:4 1 2 3
      

删:

  1. pop: 删除数组末尾的最后一个元素

    • Array.pop() :括号里面不添加元素

      var arr = [1,2,3]
      
      //使用pop弹出最后一个元素
      arr.pop()
      console.log(arr); //控制台输出结果:1 2 
      
  2. shift: 删除数组最前的一个元素

    • Array.shift() :括号里面不添加元素

      var arr = [1,2,3]
      
      //使用shift删除第一个元素
      Array.shift() 
      console.log(arr); //控制台输出结果:2,3
      
  3. splice: 截取数组中的某些内容、按照数组的索引来截取的

    • splice(从第几个开始索引,截取多少个)

      let arr = [1, 2, 3, 4, 5]
      let index = arr.indexOf(3) 
      console.log(index);//2
      //使用splice方法截取数组
      
      arr.splice(index,1)//索引号,个数
      console.log(arr); //控制台输出结果:1,2,4,5
      
    • splice(从第几个开始索引,截取多少个,替换的新元素)

      var arr = [1,2,3,4,5]
      
      //使用splice方法截取数组
      arr.splice(1,2,'我是新内容')
      console.log(arr); //控制台输出结果:1,'我是新内容',4,5
      

查:

  1. indexOf: 查找某一项的索引

    • indexOf(查找的项目) :括号里面是元素

    • 返回值:元素在数组中的索引号

    • 如果找到内容没有:返回值为**-1**

      var arr = [1,2,3,4,5]
      
      //使用indexOf查找数组中的一项
      var index = arr.indexOf(5)
      console.log(index);//控制台:4
      
  2. includs: 查找某一项是否存在

    • 返回值:布尔值

      let arr = [1,2,3,4,5]
      
      var isOk =  arr.includes(6)
      console.log(isOk);  //false
      
      var isOk =  arr.includes(1)
      console.log(isOk);  //true
      

排序方式

  1. reverse:反转数组

    • Array.reverse() :括号里不添加元素

      var arr = [1,2,3]
      
      //使用reverse方法反装数组
      arr.reverse()
      console.log(arr); //控制台:3,2,1
      
  2. sort: 字典排序

    • Array.sort() :括号里不添加元素

      var arr = [3,1,2]
      
      //使用sort方法排序
      arr.sort()
      console.log(arr); //控制台:1,2,3
      
      
  3. sort: 数值大小排序

    • 使用一个函数来实现数值大小排序

    • Array.sort(function(a,b){ return a-b})

      var arr = [3, 1, 2,11,5]
      
      arr.sort(function(a,b){
          return a-b
      })
      console.log(arr); //控制台:1,2,3,5,11
      

连接数组

  1. concat: 把多个数组进行拼接

    • Array.concat([元素1,元素2])

    • 返回值:是一个新数组

      var arr = [1, 2, 3, 4, 5]
      
      //使用concat 连接两个数组
      var new_arr = arr.concat([6,7])
      console.log(new_arr);  //控制台:1,2,3,4,5,6,7
      
  2. join: 把数组里面的每一项内容连接起来、变成一个字符串

    • 返回值: 是一个字符串

      var arr = [1, 2, 3, 4, 5]
      
      var new_str = arr.join('#')
      console.log(new_str);//控制台:1#2#3#4#5	
      

5.3 常用数组遍历方法

  1. forEach: 和for循环一个作用、遍历数组

    • 使用方法:Array.forEach(function(item,index,arr){})

    • 注意:数组的长度是多少、这个函数就会执行多少次

      var arr = [1, 2, 3, 4, 5]
      
      //使用forEach遍历数组
      arr.forEach(function(item,index,arr){
          console.log(item);  //1 2 3 4 5
          console.log(index);  // 0 1 2 3 4
          console.log(arr);   //返回整个数组
      })
      
  2. map: 对数组的项进行操作(加减乘除),返回到新数组

    • 使用方法:Array.map(function(item,index,arr){})

    • 返回值:返回一个新数组

      var arr = [1, 2, 3, 4, 5]
      var new_arr  = arr.map(function(item,index,arr){
                  return item + 2   //对元素加减乘除操作 返回到新数组
              })
              
      console.log(new_arr);        
      0: 11
      1: 12
      2: 13
      3: 14
      4: 15
      
  3. filter: 判断条件筛选、满足条件的所有数组成一个新数组

    • 使用方法:Array.filter(function(item,index,arr){})

    • 返回值:返回一个新数组

    • 使用场景:

      • 需要新数组
      • 所有满足条件的都装在新数组里面
       var arr = [1, 2, 3, 4, 5]
       var new_arr  = arr.filter(function(item,index,arr){
            return item > 2
            })
      console.log(new_arr);//控制台:3 4 5
      
  4. find: 判断条件筛选、满足条件的第一个项,返回到变量

    • 使用方法:Array.find(function(item,index,arr){})

    • 返回值:返回一个新变量

    • 使用场景:

      • 找一个变量是否在数组里?

      • 只需要找一个变量

        var arr = [1, 2, 3, 4, 5]
        var new_arr  = arr.find(function(item,index,arr){
            return item > 2   //判断条件  第一个就返回
        })
        console.log(new_arr);  //控制台:3
        
  5. every: 判断条件筛选、数组中所有项都满足、全部满足返回true

    • 使用方法:Array.every(function(item,index,arr){})

    • 返回值:返回一个布尔值

    • 使用场景:

      • 需要所有的变量都满足
      • 一个不满足都返回false
      var arr = [1, 2, 3, 4, 5]
      var new_arr  = arr.every(function(item,index,arr){
          return item > 2
      })     
      console.log(new_arr);  //控制台:false
      
  6. some: 判断条件筛选、数组中只有一个数存在、就返回true

    • 使用方法:Array.some(function(item,index,arr){})

    • 返回值:返回一个布尔值

    • 使用场景:

      • 只要一个值存在就返回

      •   var arr = [1, 2, 3, 4, 5]
          var new_arr  = arr.some(function(item,index,arr){
              return item > 2
          })       
          console.log(new_arr);   //控制台:true   
        
  7. reduce: 遍历数组、累加求和数组项、从左至右

    • 使用方法:Array.reduce(function(s, item,index,arr){},0) 0是初始值

    • 返回值:返回一个累加求和的值

    • 使用场景:需要累加求和数组里面的值

      var arr = [1, 2, 3, 4, 5]
      
      var new_arr  = arr.reduce(function(s,item,index,arr){
          return s + item
      },0)
      console.log(new_arr);    //控制台:  15    
      

5.4 数组的排序方式

  1. 冒泡排序法

    function maopao() {
        //冒泡排序法
        var arr = [89, 98, 78, 68, 76]
    
        for(var i = 0; i < arr.length-1;i++){
            for(var j = 0;i < arr.length-1-j;j++){
                if(arr[j]<arr[j+1]){
                    var temp = arr[j]
                    arr[j] = arr[j+1]
                    arr[j+1] = temp
                }
            }
        }
        console.log(arr);
    }
    maopao()
    
  2. 选择排序法

            function swap(arr,i,j){
                var temp = arr[i]
                arr[i] = arr[j]
                arr[j] = temp
            }
    
            function choose(){
                //选择排序法
                var arr = [89, 98, 78, 68, 76]
                var n = arr.length
                console.log(n);
                for(var i = 0; i < n-1;i++){
                     minIndex = i
                    for(var j = i+1;j < n;j++){
                        if(arr[minIndex]>arr[j]){
                            minIndex = j
                        }
                    }
                    swap(arr,minIndex,i)
                }
                console.log(arr);
            }
            choose()
    

5.5 交换数组元素通用方法

function swap(arr, i, j) {
var temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}

六、字符串

6.1 创建字符串:

  • 概念:两种方式创建没有任何区别、除了在控制台显示有区别之外

  • 字面量创建

    var str = 'hello'
    
  • 构造函数创建

    var str = new String('hello')
    

6.2 字符串操作:

  • 字符串长度:str.length (空字符也是一个字符)

  • 字符串索引:str[0]

    • 可以通过索引访问每一个字符
    • 字符值只能访问不能改变(可以在后面+(添加字符))
  • 包装数据类型:

    • toString()
  • 模板字符串:

    • 使用方法 :反引号

    • 动态引用遍历变量:${变量名}

              productList.forEach(function (item, index) {
                  list_start = list_start + `
                          <tr>
                              <td ><img class="tableImg" src="${item.url}" alt=""></td>
                              <td>${item.name}</td>
                              <td>¥${item.price}</td>
                              <td>${item.num}</td>
                              <td>¥${item.singlePrice}</td>
                              <td>
                                  <div>移入收藏</div>
                                  <div>删除</div>
                              </td>
                          </tr>
                      `
              })
      

6.3 字符串常用方法:

增:

  • ​ 概念:使用+号连接符在后面增加字符串

  • concat: 连接字符串,返回连接之后的字符串

    • str.concat(): 括号里输入后面要添加的字符串

      var str = 'java'
      
      console.log(str.concat('script')); //javascript
      

删:

  • substring: 第一个索引号+结束索引号来截取字符串的

    • 语法: substring(开始索引号,结束索引号) 左闭右开法则
    • 注意:使用的是两个索引号来决定截取
    var str = 'javascript'
    console.log(str.substring(1,3)); //av
    
  • substr: 开始索引+截取字符个数来截取字符串的

    • 语法: substr(开始索引号,截取个数)

    • 注意:使用的是索引号加个数

      var str = 'javascript'
      console.log(str.substring(1,3)); //ava
      

改:

  • replace: 使用字符串替换一些字符串

    • 用法:str.replace(‘原字符’,‘替换字符’)

    • 注意:只能替换一次

      var str = 'java script'
      
              console.log(str.replace('java','HHH'));//HHH script
      

查:

  • charAt(): 用索引号查找字符、输出字符

    • str.charAt(索引号) : 括号里输入索引号

    • 返回值:字符

    • 注意:没有对应索引号 返回值为空字符串 ‘’

      var str = 'java'
      str.charAt(0)
      console.log(str.charAt(0)); //j
      
  • indexOf(): 用字符查找索引号、输出索引号

    • str.indexOf(字符): 括号里输入字符

    • 返回值: 索引号

    • 注意: 没有对应的返回值为-1

      var str = 'java'
      console.log(str.indexOf('j')); // 0
      console.log(str.indexOf('d')); //-1
      

分隔字符、去空白、判断开始结束字符串、大小写字符

  • split: 分割字符串,分割之后的字符存入数组返回

    • str.split(‘ ’): 括号里输入从那个字符分割

    • 返回值: 返回一个新数组

      var str = 'java script c python'
      
      var list = str.split(' ')  //通过字符串里的字符分割
      console.log(list);  // ['java', 'script', 'c', 'python']
      
  • trim: 去除字符串两端的空白符

    • str.trim() :括号不需要输入元素

    • 返回值:去掉空格的新字符

      var str = '    java  script  '
      //只去除元素两端的空白
      console.log(str.trim());//java  script
      
  • startWith()&endWith: 判断字符串是否开始或者结束

    • str.starWith(子字符串) :括号里是判断的字符
    • 返回值: 布尔值
    var str = '    java  script  '
    
    console.log(str.startsWith('java'));//false
    console.log(str.trim().startsWith('java'));//true
    
  • toLowerCase()&toUpperCase: 转成小写字母和大写字母

    • str.toLowerCase():

    • 返回值: 一个新的字符串

       var str = '    jAva  script  '
              console.log(str.trim().toLocaleLowerCase().startsWith('java'));//true
      

严格模式

  • 概念:js相对不严谨、所以使用严格模式来对写的内容做了要求

  • 不严格:

    • 声明变量可以不使用var关键字
    • 形参重复
  • 严格:

    •   'use strict'
      

七、对象

7.1 简单了解对象

  • 概念:对象是一个具体的事物

    • 拥有属性、方法
  • 创建对象

    • 构造函数

      var  obj = new Object()
      obj.name = 'jack'
      obj.age = 18
      obj.say = function(){
      
      }
      console.log(obj);
      
    • 字面量创建

      //定义一个空的对象
      var obj2 = {}
      //创建有内容的对象
      var obj2 = {
          naem: 'java',
          age:18,
          say:function(){
          }
      }
      
  • 访问对象属性(两种属性)

    • 静态:obj.属性名 {就可以访问}

    • 动态: obj[变量名] {动态输入变量访问属性}

      ``		    //创建有内容的对象
      var obj2 = {
          name: 'java',
          age:18,
          say:function(){
              return '说话'
          }
      }
      
      //f访问对象属性
      console.log(obj2.name); //java
      console.log(obj2.age); //18
      
      // 动态访问对象属性名,属性名是变量
      var str = 'name'
      console.log(obj2[str]); // java
      
  • 访问对象方法

    var str = obj2.say()   
    console.log(obj2.say())
    

7.2 for in 和 for of

  • for - in:

    • 遍历Objct对象,遍历所有的属性、属性值

      var obj2 = {
          name: 'java',
          age:18,
      }
      
      for(var key in obj2){
          console.log(key,obj2[key]);
      }
      //  name java
      //  age 18
      
  • for -of:

    • 遍历数组、字符串

      var arr = [10,20,30,40]
      for(var key1 of arr){
          console.log(key1);
      }
      
    • 例题引申

      • 统计字符串周昂i不同字符的出现次数
      • 创建一个空对象、存储每一个字符的个数
      • 利用for - of 和计数器传值给对象
      • 里面有值就让计数器++
      • 里面没有undefined就创建 obj[num] = 1
      a: 3
      b: 2
      c: 4
      d: 2
      e: 2
      f: 2
      g: 2
      k: 2
      m: 2
      
                  var str = 'abcdefabcadefkmmkggcc'
                  var obj = {}
      
                  for(var num of str){
                      if(obj[num]){   //obj[a]是否在obj{}
                          obj[num]++   //将a属性值加1
                      }else{
                          obj[num] = 1  //创建一个属性a 并且赋值1
                      }
                  }
                 console.log(obj);
      

7.3math数学对象

  • 概念:处理数学相关问题

  • Math.属性

  • Math.方法()

  • Math.random(): ==随机

    • 概念:处理数学相关问题
      • Math.属性
      • Math.方法()
  • Math.random(): 随机数

    • 方法: Math.random()*随机数范围+随机数起始值

      function getrandom(a,b){
          var max = Math.max(a,b)
          var min = Math.min(a,b)
          var range = max - min
          return Math.random()*range+min
      }
      
    • 例题引申:生成10000个随机数0~10,统计每个随机数出现次数

      • 创建一个空对象存储0-10的对象

      • 10000次循环里面 生成一个随机数

      • 判断0-10 在对象里嘛 在就++ 不在就创建

                function getNUM(){
                    var obj = {}
                    for(var i = 0; i <= 10000; i++){
                        var a = Math.floor(getrandom(0,11))
                        if(obj[a]){
                            obj[a]++
                        }else{
                            obj[a] = 1
                        }
                    }
                    console.log(obj);
                }
                
                        // {0: 940, 1: 906, 2: 902, 3: 850, 4: 857, 5: 922, 6: 927, 7: 873, 8: 952, 9: 925, 10: 947}
        
        
  • Math.ceil(数值):向上取整 10.1==>11 ||

  • Math.floor(数值):向下取整 10.1==>10

  • Math.round(数值):四舍五入 10.4==>10 ||10.6 ==>11

  • 进制转换:

    • parseInt()把num,当成对应进制数来计算 其他进制-> 十进制 :

                  var num = 100
      
                  console.log(parseInt(num,2)); // 4
                  console.log(parseInt(num,8)); // 64
                  console.log(parseInt(num,16)); //256
      
    • toString() 把num的值转化成 对应进制的值 十进制–> 其他进制

                  var num = 100
      
                  console.log(num.toString(2)); //1100100
                  console.log(num.toString(8)); //144
                  console.log(num.toString(16)); //64
      

随机颜色值:

        function getRandom16Color(){
            var r = getRandom(0,256)
            var g = getRandom(0,256)
            var b = getRandom(0,256)
            var r1 = r.toString(16)
            r1 = r1.length == 1?'0'+r1:r1
            var g1 = g.toString(16)
            g1 = g1.length == 1?'0'+g1:g1
            var b1 = b.toString(16)
            b1 = b1.length == 1?'0'+b1:b1
            
            var rgbColor = `#${r1}${g1}${b1}`
            console.log(rgbColor);
            document.querySelector('div').style.backgroundColor = rgbColor
        }
        getRandom16Color()

        function getRandomRGBColor() {
            var r = getRandom(0,256)
            var g = getRandom(0,256)
            var b = getRandom(0,256)
            var rgb = `rgb(${r},${g},${b})`
            // document.write(rgb)
            document.querySelector('div').style.backgroundColor = rgb
        }
        // getRandomRGBColor()

        function getRandom(m, n) {
            var max = Math.max(m, n)
            var min = Math.min(m, n)
            return Math.floor(Math.random() * (max - min) + min)
        }

日期:处理时间

  • 创建日期时间:var data = new Date()

    var data = new Date(2022,4,20,14,20,10)
    var data = new Date('2022-4-20 14:20:10')
    
常用方法
getFullYear
getMonth
getDate
getHours
getMinutes
getSeconds
getDay
getTime

7.4 this关键字(ES6新语法)

在不同场景下表示不同对象

  • 第一种表示:事件源
    事件处理函数this =>事件源头
    第二种表示:window对象
    普通函数this=>window
    定时器参数函数this=>window
    自执行函数this=>window
    第三种表示:正在调用执行方法的对象
    对象objectthis=>当前正在调用执行方法的对象

改变this指向

  • call:

    • 函数名.call(要指向的对象,参数1,参数2.。。。)
  • apply:

    • 函数名.apply(要指向的对象,【参数1,参数2】)
  • bind:

    • 函数名.bind(要指向的对象)

    • 返回值;改变this指向的新函数

    • 新函数(参数1,参数2.。。)

      var jackObj = {
      name: 'jack',  //姓名
      phoneBattery: 70, //手机电量
      //给手机充电
      changeBattery: function(num){
      this.phoneBattery = num
      }
      }
      
      console.log('jack原来手机电量:',jackObj.phoneBattery);
      jackObj.changeBattery(100)
      console.log('jack充电后手机电量:',jackObj.phoneBattery);
      
      var roseObj = {
      name: 'rose', //姓名
      phoneBattery: 10,
      }
      
      console.log('rose原来手机电量:',roseObj.phoneBattery);
      jackObj.changeBattery.call(roseObj,99.99)
      console.log('rose充电后手机电量:',roseObj.phoneBattery);
      

八、BOM浏览器对象模型

8.1 概述

提供我们操作浏览器的能力,是浏览器窗口对象,核心对象是 window。
创建方式: 系统自动创建

8.2 History对象

History对象可以用来操作浏览器向前或向后翻页

History.back()  //后退
History.forward()   //前进
go(-2)//可以用来跳转到指定的页面,它需要一个整数作为参数(正负表示向前或向后跳转)

8.3 location 位置

Location对象中封装了浏览器的地址栏的信息,如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)

console.log(location);          //输出location对象
console.log(location.href);     //输出当前地址的全路径地址
console.log(location.origin);   //输出当前地址的来源
console.log(location.protocol); //输出当前地址的协议
console.log(location.hostname); //输出当前地址的主机名
console.log(location.host);     //输出当前地址的主机
console.log(location.port);     //输出当前地址的端口号
console.log(location.pathname); //输出当前地址的路径部分
console.log(location.search);   //输出当前地址的?后边的参数部分

修改地址:

location.href = "https://www.baidu.com";

assign():用来跳转到其它的页面,作用和直接修改location一样

location.assign("https://www.baidu.com");

reload():用于重新加载当前页面,作用和刷新按钮一样,如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面

location.reload(true);

replace():可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,它不会生成历史记录,不能使用回退按钮回退

location.replace("https://www.baidu.com");

8.4 Navigator对象

Navigator代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器,由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了,一般我们只会使用userAgent来判断浏览器的信息,userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent,如下代码:

var ua = navigator.userAgent;
console.log(ua);

8.5 Screen对象

用户显示屏幕相关属性

注意:没有应用于 screen 对象的公开标准,不过所有浏览器都支持该对象。

8.6 常用窗口属性

两个属性可用用于确定浏览器窗口的尺寸。

这两个属性都以像素返回尺寸:

  • window.innerHeight - 浏览器窗口的内高度(以像素计)
  • window.innerWidth - 浏览器窗口的内宽度(以像素计)
    浏览器窗口(浏览器视口)不包括工具栏和滚动条。

对于 Internet Explorer 8, 7, 6, 5:

  • document.documentElement.clientHeight
  • document.documentElement.clientWidth

  • document.body.clientHeight
  • document.body.clientWidth

一个实用的 JavaScript 解决方案(包括所有浏览器):该例显示浏览器窗口的高度和宽度(不包括工具栏和滚动条)

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
    var w = window.innerWidth
        || document.documentElement.clientWidth
        || document.body.clientWidth;

    var h = window.innerHeight
        || document.documentElement.clientHeight
        || document.body.clientHeight;

    console.log(w);
    console.log(h);
</script>
</body>
</html>

8.2 弹框相关

alert()信息提示框(弹出消息)
confirm()信息确认框 (弹出两个选项)
prompt()信息输入框 (弹出获取输入框)
  • alert():信息提示框

    • 注意事项:window对象属性调用方法的时候可以不加window
  • confirm() ;信息确认框

    • 数据类型:布尔值
    • 两个选项卡
      • 确定==>true
      • 取消==>flase
  • prompt(): 信息输入框

    • 确定 输入框内容
      • 数据类型:字符串:string
    • 取消: null

8.3 打开和关闭网页

  • open(“网址”):打开指定网页

  • close():关闭当前网页

      		//消息确认框获取
      	    var isok =  confirm('是否确认')
            if(isok){
            // open('https://www.baidu.com/')
            close()
    
            }else{
                alert('点击确认才能打开')
            }
    

8.4 定时器

  • 执行一次:setTimeout()

    • 只是倒计时1次
    var timer = setTimeout(function(){
        console.log('2秒我就出现');
    },2000)  //倒计时2000(2秒倒计时)
    

8.5 循环定时器

  • 循环执行:setInterval()

    • 循环计时1秒钟执行一次(循环)
    var count = 1		//写在循环函数外面,才不会重复定义
    var timeOut = setInterval(function(){
        count++			//让计数器加1
        console.log(count);
        if(count==5){	//设置计数器的结束值
            clearTimeout(timeOut)   //<结束计时器>
        }
    },1000)  //每一秒执行一次1000(1秒)
    
  • 结束记时间:clearTimeout(循环计时函数)

8.6 滚动事件

  • window.onscroll:监测滚动条是否滚动

            window.onscroll = function(){
                console.log('d1'+document.documentElement.scrollTop);
                console.log('d2'+document.body.scrollTop)
                console.log('滚动了');
            }
    d1200
    bom.html:89 d20
    bom.html:90 滚动了
    
  • 概念:滚动距离实际时页面文档卷入的高度 == 滚动条距离顶部高度

  • document.documentElement.scrollTop

  • 兼容写法:document.body.scrollTop 没有DOCTYPE声明时用

  • 示例:点击回到顶部

    //css部分
	<style>
        div{
            width: 1000px;
            height: 18000px;
            background-color: skyblue;
        }
        button{
            position: fixed; //设置固定定位
            left: 100px;
            top: 100px;
        }
    </style>
    
	//script部分
	<script>
    function put(){
        document.documentElement.scrollTop = 0
    }
    </script>

	//body部分
	<button onclick="put()">回到顶部</button> //使用onclick = 'put()'点击事件
  • 例题延申:平滑回到顶部

    function put() {
        var topWindow = document.documentElement.scrollTop  //获取顶部的距离
        console.log(typeof topWindow)                       //number
        //设置一个循环计时器
        var timer = setInterval(function () {
            //计时器结束条件
            if (topWindow <= 0) {   //当顶部距离小于等于0时结束timer
                clearTimeout(timer) //结束计时器
            }
            topWindow = topWindow - 500  //每一次循环减去500
            document.documentElement.scrollTop =topWindow   //再把每次减去的值赋值给他
    
        }, 50)
        }
    

九、DOM-文档对象模型

概述:当网页被加载的时候、浏览器就会创建页面的文档对象模型(Document Object Model)。HTML DOM 是关于如何获取、更改、添加或删除 HTML 元素的标准。

image-20220715153454314

9.1 document对象

  1. document对象

    1. document对象是window对象中的子对象。
    2. document对象除了write()方法外,跟其他对象一样,也有自身一套属性和方法。
    3. document对象,即文档对象。顾名思义,其实很好理解,文档对象嘛,操作的都是HTML文档。为了更好理解什么叫“HTML文档”,
  2. document对象属性

    document对象属性
    属性                  说明
    title                文档标题,即title标签内容
    URL                文档地址
    fileCreateDate   文档创建日期
    fileModifiedDate  文档修改时间(精确到天)
    lastModified      文档修改时间(精确到秒)
    fileSize           文档大小
    fgColor            定义文档的前景色
    bgColor           定义文档的背景色
    linkColor         定义“未访问”的超链接颜色
    alinkColor        定义“被激活”的超链接颜色
    vlinkColor        定义“访问过”的超链接颜色
    
  3. document对象方法

    document.write()                    输入文本到当前打开的文档
    document.writeIn()                  输入文本到当前打开的文档,并添加换行符“\n”
    document.getElementById()       获取某个id值的元素
    document.getElementsByName()  获取某个name值的元素,用于表单元素
    上面列出了document对象常用的属性和方法,跟window对象的学习一样
    

9.2 获取html元素

getElementById(‘id属性值’)单个元素
getElementsByClassName(‘class属性’)伪数组
getElementsByTagName(‘标签名’)伪数组
getElementsByName(‘name属性’)伪数组
querySelector(‘选择器写法’)首个元素
querySelectorAll(选择器写法)伪数组
  1. getElementById(id属性值):id名获取

    • 通过元素id名获取整个元素

      <h2 id="title1" class="t1">h2标题</h2>
      
      var h2Ele = document.getElementById('title1')
      console.log(h2Ele); //<h2 id="title1" class="t1">h2标题</h2>
      console.log(h2Ele.innerHTML); //h2标题 获取内容
      console.log(typeof h2Ele.innerHTML);//string
      
  2. getElementsByClassName(class属性值):class名获取

    • 通过类名获取多个元素【伪数组】

    • 伪数组:

      • 不能使用常用方法
      • 可以用索引号和length属性
      var getClass = document.getElementsByClassName('t1')
      // console.log(getClass[0]);//h2 id="title1" class="t1">h2标题</h2>
      for(var i = 0;i < getClass.length;i++){
          console.log(getClass[i]);
          // <h2 id="title1" class="t1">h2标题</h2>
          // <p id="title2" class="t1">p元素1</p>
          // <p id="title3" class="t1">p元素2</p>
      }
      
  3. getElementsByTagName(标签名):p||h2 标签名获取

    • 通过标签名获取多个元素【伪数组】

       var getTageName = document.getElementsByTagName('p')
        console.log(getTageName[0]); //<p id="title2" class="t1">p元素1</p>
      
  4. getElementsByName(name值):name的值

    • 通过标签名获取多个元素【伪数组】

      var getName = document.getElementsByName('getme')
      console.log(getName[0]);//<input type="text" name="getme">
      
  5. querySelector(‘选择器写法’) 单个首个

    • 选择器怎么写 括号里面就怎么写

    • 选中到第一个符合条件的元素

      <h2 id="title1" class="t1">h2标题</h2>
      <p id="title2" class="t1">p元素1</p>
      <p id="title3" class="t1">p元素2</p>
      
      var selectorGet = document.querySelector('.t1') //获取类名为t1的
      console.log(selectorGet); //<h2 id="title1" class="t1">h2标题</h2>
      
      
  6. querySelectorAll (‘选择器写法’) 多个元素伪数组

    • 选中所有符合的元素

    • 返回到伪数组中

      <h2 id="title1" class="t1">h2标题</h2>
      <p id="title2" class="t1">p元素1</p>
      <p id="title3" class="t1">p元素2</p>
      
      var selectorGet = document.querySelectorAll('.t1')
      console.log(selectorGet[0]); //<h2 id="title1" class="t1">h2标题</h2>
      
      

9.3 操作元素内容

  1. innerHTML:innerHTML可以解析标签内容,获取非表单内容,输出内容为:内容

                var selectorGet = document.querySelector('#title')
                var content = selectorGet.innerHTML
                console.log(content);
    
                //设置内容
                selectorGet.innerHTML = '<h2>新的内容哦哦</h2>'
                var content = selectorGet.innerHTML
                console.log(content);
    
  2. innerText:innerText不可以解析标签内容,会以文本形式输出< h1>内容< /h1>

                var selectorGet = document.querySelector('#title')
                var content = selectorGet.innerText
                console.log(content);
    
                //设置内容
                selectorGet.innerText = '<h2>新的内容哦哦</h2>'
                var content = selectorGet.innerText
                console.log(content);
    
  3. value:操作的是表单元素内容、你可以获取表单的输入框的内容

9.4 操作CSS样式

  1. 元素.style

    • 元素.style.color(属性名) = “属性值”

    • 行内样式:添加的所有代码都在行内样式里

    •   设置值
        ele.style.样式名 = 样式值 
        取值 
        var value = ele.style.样式名
      
  2. 样式列表.classList(非行间样式)

    1. ele.className = 类名
    2. ele.classList.add(类名1)//添加样式
    3. ele.classList.remove(类名) //删除
  3. window.getComputedStyle(ele).样式名

    • 获取样式的值

      <style>
          .add {
              width: 100px;
              height: 100px;
              background-color: skyblue;
              background: red;
          }
      </style>
      <script>
      
          var h2ele = document.querySelector('h2')
          var divEle = document.getElementById('divId')
          divEle.classList.add('add')  //添加样式
          var w = window.getComputedStyle(divEle).width  //getComputedStyle(divEle)括号里添加divEle
          console.log('width',w);  //width 100px
      
      </script>
      
      
    • 例题引申:点击移动小方块

      var divEle = document.querySelector('div')
              divEle.classList.add('add')
              var initLeft = window.getComputedStyle(divEle).left
              divEle.style.left = initLeft  //初始化给值
      
              //最终到达值 = 初始值 + 500
              var  goal = parseInt(initLeft) + 500
      
              //为小方块设置点击事件
              divEle.onclick = function(){
                  
      
                  // //设置一个定时器 每次执行移动 知道goal停止定时器
                  var timer = setInterval(function(){
                      if(parseInt(divEle.style.left) == goal){
                          clearInterval(timer)
                      }else{
                          divEle.style.left = parseInt(divEle.style.left) + 50 + 'px'
                      }
                  },50)
                  
                  console.log(divEle.style.left);
      
              }
      

9.5 操作属性

  1. 设置、更改属性:

    • setAttribute(属性名,属性值) 注意:引号~~~~~

      var getA = document.querySelector('a')
      getA.setAttribute('href',"http://www.jd.com")  //更改属性
      getA.innerHTML= '京东'   //更改内容
      
  2. 获取属性:

    • getAttribute(属性名)

      var getImg = document.querySelector('img')
      var getAlt = getImg.getAttribute('alt')
      console.log(getAlt); //图片
      
  3. 删除属性:

    • removeAttribute(属性名)

      var getImg = document.querySelector('img')
      getImg.removeAttribute('alt') //删除alt属性
      console.log(getImg); //<img src="http://www.baidu.com">
      

9.5 DOM节点类型

概念:从dom角度出发每个html标签元素都可以看作为节点(对象)

  1. 节点类型

    1. 标签元素称为:元素节点
    2. 标签内容称为:文本节点
    3. 标签属性称为:属性节点
    4. 整个html文档:文档节点(document)
  2. 常用节点类型和方法

    1. 元素节点:通过getElementBy…获取元素节点
    2. 属性节点:通过getAttribute获取元素节点
    3. 文本节点:通过innerText 获取元素的文本节点
  3. DOM节点树形结构

    image-20220715161359226

  4. 节点关系

    1. 根节点
    2. 父节点
    3. 子节点
    4. 兄弟节点
    5. 注意事件:元素节点之间有空白的文本节点

9.6 获取元素节点

  1. 获取节点

    • getElement系列 ->
    • querySelector系列 ->
    • 层次结构获取节点系列->
  2. 文本节点

    • childNodes 所有子节点
    • parentNode 父节点
    • nextSibling 下一个兄弟节点
    • previousSibling 上一个兄弟节点
  3. 元素节点

    • previousElementSibling 上一个元素兄弟节点*
    • nextElementSibling 下一个元素兄弟节点*
    • parentElement <==> parentNode*
    • children 子元素节点*
    • firstElementChild*
    • lastElementChild*
  4. 非常规节点

    • body document.body
    • head document.head
    • html document.docuemntElement

9.7 操作DOM节点

判断节点类型

nodeTypenodeNamenodeValue
元素节点1标签名大写null
属性节点2属性名属性值
文本节点3#text文本内容

动态操作节点

  1. 创建节点
    document.createElement('div')    //创建元素
    document.createTextNode('元素一')    //创建元素内容
    
    • document.createElement(‘div’) //创建元素
    • document.createTextNode(‘元素一’) //创建元素内容
    • divEle.appendChild(content) //将元素内容加到元素中去
  2. 添加节点
    • 父节点.appendChild(子节点)

    • 父节点.insertBefore(新子节点,原子节点)

       // 创建一个元素
              var divEle = document.createElement('div')
              var content = document.createTextNode('元素二') //创建元素内容
              divEle.appendChild(content) //把元素内容追加到元素中去
      
              //在元素后面追加元素
              document.body.appendChild(divEle) //添加元素
              元素一
              元素二
      
              //在元素前面插入元素
              document.body.insertBefore(divEle, document.body.firstElementChild)
              元素二
              元素一
      
  3. 删除节点
    父节点.removeChild(子节点)
    子节点.remove()
    
  4. 克隆节点
    • 节点.cloneNode()
      • false 默认 不克隆子节点
      • true 克隆节点
  5. 替换节点
    • 父节点.replaceChild(新节点,原节点)

9.8 获取元素尺寸(宽、高)三种方式

  1. 获取非行间样式

    非IE
    window.getComputedStyle(元素).样式名
    IE(现在已经不更新了,只作为了解)
    元素.currentStyle.样式名
    
  2. 获取元素尺寸(宽、高)三种方式

    内容宽 + padding元素.clientWidth
    内容宽window.getComputedStyle(元素).width
    内容宽 + padding + border元素.offsetWidth

9.9 元素位置

<script>
元素位置
function test1(){
var divEle = document.querySelector('div')
var pEle = document.querySelector('p')
console.log('divEle.offsetTop:',divEle.offsetTop, ' divEle.offsetLeft :', divEle.offsetLeft) 
console.log('pEle.offsetTop :',pEle.offsetTop, ' pEle.offsetLeft :', pEle.offsetLeft) 
}
test1()
</script>

十、事件

10.1 事件简介

概述:

当我们点击一个按钮的时候,会弹出一个对话框。在JavaScript中,“点击”这个事情就看作一个事件。“弹出对话框”其实就是我们在点击事件中做的一些事。

事件三要素

  • 事件源: 在谁身上触发事件 btn
  • 事件类型: 点击,移动,… onclick
  • 事件处理函数: 触发事件后执行的操作 function(){}

10.2 事件对象event

1. 简介:

  • 每触发一个事件都会生成事件对象
  • 事件对象包含对事件的描述信息
    1. 点了那个位置、坐标是多少
    2. 触发键盘事件、按的那个键

2. 获取事件对象

  • 注意事项:每一个事件处理函数的形参位置、默认第一个都是事件对象

    e = e || window.event //事件对象
    button.onclick = function(e){
               e = e || window.event
              }
    

3. 点击事件的光标坐标点获取

概念:每一个点击事件的坐标点都不是一对,因为要有一个相对的坐标系

  1. 相对事件源(点击的元素)
  2. 相对页面
  3. 相对浏览器窗口

4. 获取光标属性

  • 使用方法:事件(event).offsetX

    clientXclientY浏览器窗口
    offsetXoffsetY自身
    pageXpageY页面
button.onclick = function(e){
              e = e || window.event
              e.clientX  e.clientY
          }

10.3 事件类型

  1. 鼠标事件

    click :点击事件
    dbclick :双击事件
    contextmenu : 右键单击事件
    mousedown :鼠标左键按下事件
    mouseup :鼠标左键抬起事件
    mousemove :鼠标移动
    mouseover :鼠标移入事件
    mouseout :鼠标移出事件
    mouseenter :鼠标移入事件 事件冒泡
    mouseleave :鼠标移出事件
    
  2. 表单事件

    input 内容输入事件
    change 内容改变事件
    submit  表单提交事件
    

    注意事项:

    1. 表单提交事件的作用:对表单内容进行验证

    2. 阻止表单默认行为:

      阻止表单默认行为: e.preventDefault
      
  3. 焦点事件

    blur 失去焦点
    focus 获取焦点
    
  4. 浏览器相关事件

    load : 页面全部资源加载完毕
    scroll : 浏览器滚动的时候触发
    resize :页面大小事件
    
  5. 键盘事件

    onkeydown  键盘按下
    onkeyup    键盘抬起
    键码: 每个键都有一个键码,组合按键 ctrlKey、shiftKe、yaltKey
    
1.1 鼠标事件案例

image-20220426165828098

<style>
.add {
width: 100px;
height: 100px;
background-color: skyblue;
font-size: 24px;
line-height: 100px;
text-align: center;
color: red;
font-weight: 900;
}
</style>

<body>
<div>标题</div>
<script>
function test1() {
var divEle = document.querySelector('div')
divEle.classList.add('add')
//鼠标移入时的状态
divEle.onmouseover = function(){
divEle.style.color = 'yellow'
}
//鼠标移出时的状态
divEle.onmouseout = function(){
divEle.style.color = 'red'
}
}
test1()
</script>
</body>
1.2 表单事件示例

image-20220426204212082

<!DOCTYPE html>
<html lang="en">

<head>
    <title>初始表单验证</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        form {
            width: 500px;
            margin: 100px auto;
            padding: 20px;
            border: 1px solid gray;
        }

        form input {
            width: 90%;
            height: 40px;
            margin-bottom: 30px;

        }

        form p {
            font-size: 16px;
            color: red;
        }
    </style>
</head>

<body>
    <form action="../homework/index.html">
        <input type="text" name="username" placeholder="请输入用户名">
        <p class="user-msg"></p> <br>
        <input type="password" name="password" placeholder="请输入密码">
        <p class="pass-msg"></p> <br>
        <input type="submit">
    </form>

    <script>
        var formEle = document.querySelector('form')
        //给表单设置提交事件
        formEle.onsubmit = function (e) {
            e = e || window.event
            e.preventDefault() //阻止默认action动作

            var btnUser = document.querySelector('input[name="username"]')
            var btnPas = document.querySelector('input[name="password"]')
            var formEle = document.querySelector('form')
            var pUser = document.querySelector('.user-msg')
            var pPass = document.querySelector('.pass-msg')

            //获取用户名和密码的值
            var userVal = btnUser.value
            var btnPas = btnPas.value


            //判断是否为空账号
            if (!isNullUser()) {
                return
            }

            //判断是否为空密码
            if (!isNullPass()) {
                return
            }

            //判断是否正确账号密码
            if(!isOk_UP){
                return
            }

            //成功登录
            alert('成功登录')
            location.href = './index.html'

        }

        //判断是否账号为空
        function isNullUser() {
            if (userVal == '') {
                pUser.innerHTML = '账号不能为空'
                return false
            } else {
                pUser.innerHTML = ''
                return true
            }
        }

        //判断是否密码为空
        function isNullPass() {
            if (btnPas == '') {
                pPass.innerHTML = '密码不能为空'
                return false
            } else {
                pPass.innerHTML = ''
                return true
            }
        }

        //判断是否账号密码正确
        function isOk_UP() {
            //测试表单输入是否正确
            if (userVal != 'admin' || btnPas != '123456') {
                alert('密码或账号输入错误')
                return false
            }else{
                return true
            }
        }
    </script>
</body>

</html>
1.3 焦点事件案例
// <input type="text" name="test" id="t1">
// <p></p>

var inputEle = document.querySelector('input[name="test"]')
var pEle = document.querySelector('p')

inputEle.onblur = function(){
    // alert('鼠标失去焦点')
    pEle.innerHTML = '鼠标失去焦点'
}

inputEle.onfocus = function(){
    // alert('鼠标获取焦点')
    pEle.innerHTML = '鼠标获取焦点'
}
1.4 浏览器事件示例
window.onload = function () {
var h2Ele = document.querySelector('h2')
console.log('h2Ele ', h2Ele)
h2Ele.innerHTML = '页面加载完事件111'
}
1.5 键盘事件示例
document.onkeyup = function(e){    //网页接受键盘事件的号码
            e = e || window.event
            var keyCode = e.keyCode || e.which //获取键盘号码
            if(keyCode == 13 && e.ctrlKey){
                alert('登录成功')
            }
            alert(keyCode)  //打印点击键盘号码
        }
1.6 事件附加题

image-20220426190256421

实现:

  1. 一个大盒子里面包含一个小盒子
  2. 小盒子随着鼠标的移动而移动
  3. 小盒子随着鼠标移入大盒子而出现
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .big {
            width: 300px;
            height: 300px;
            background-color: skyblue;
            position: relative;
            margin: 100px auto;
        }

        .small {
            width: 100px;
            height: 100px;
            position: absolute;
            background-color: pink;
            left: 0px;
            top: 0px;
            /* 当前元素事件不起作用 */
            pointer-events: none;
            display: none;
        }
    </style>
</head>

<body>
    <div>
        <p></p>
    </div>

    <script>
        var divEle = document.querySelector('div')
        divEle.classList.add('big')
        var pEle = document.querySelector('p')
        pEle.classList.add('small')

        //给大盒子绑定鼠标移动事件、返回移动值
        divEle.onmousemove = function (e) {
            e = e || window.event //事件对象
            console.log('X ', e.offsetX, ' Y :', e.offsetY);

            //将现在的鼠标在的x,y值传给小盒子,并让鼠标永远在小盒子中间
            var bigPosX = e.offsetX - pEle.clientWidth / 2
            var bigPosY = e.offsetY - pEle.clientHeight / 2


            // 小盒子的边界问题
            //右边界临界值 = 大盒子的宽度 - 小盒子的宽度
            var maxRight = divEle.clientWidth - pEle.clientWidth
            //下边界临界值 = 大盒子的高度 - 小盒子的高度
            var maxBottom = divEle.clientHeight - pEle.clientHeight
            // 左边界
            if (bigPosX < 0) {
                bigPosX = 0
            }
            //右边界值
            if (bigPosX > maxRight) {
                bigPosX = maxRight
            }
            //上边界值
            if (bigPosY < 0) {
                bigPosY = 0
            }
            //下边界值
            if (bigPosY > maxBottom) {
                bigPosY = maxBottom
            }

            //将值赋值给小盒子的position的left和top属性中去
            pEle.style.left = bigPosX + 'px' //将鼠标X轴的位置传给小盒子的position
            pEle.style.top = bigPosY + 'px' //将鼠标y轴的位置传给小盒子的position
        }

        //小盒子隐藏显示:  摸到大盒子显示小盒子
        divEle.onmouseover = function(){
            pEle.style.display = 'block'
        }
        divEle.onmouseout = function(){
            pEle.style.display = 'none'
        }

    </script>
</body>

</html>

10.4 事件绑定方式

  1. 属性事件:结构与行为没有分离(虽说不好、但是后面的主流框架都是用的这种方式)

    <h2 onclick="alert('属性事件')">按钮</h2>
    
  2. 赋值事件(DOM0级)

    • 后面的事件会覆盖前面相同的事件
    ele.onclick = function () {
    alert('事件绑定赋值方式')
    }
    
  3. 事件监听(DOM2级)

    • 后面的事件会覆盖前面相同的事件

         ele.addEventListener(事件类型,事件处理函数)              
      
  4. 不同方式的区别

    • 结构于行为分离
    • 赋值:后面的事件会覆盖前面相同类型的事件
    • 监听:后面不会覆盖前面事件
  5. 移出事件

    • 赋值式:

      ele.onclick = null
      
    • 监听式:

      var pEle = document.querySelector('p')
      function test() {
          alert('测试监听删除')
      }
      pEle.addEventListener('click',test)
      pEle.removeEventListener('click',test)
      

10.5 事件传播

概念:当元素触发一个事件的时候、它的父元素也会触发相同的事件、父元素的父元素也会触发相同的元素。

大白话:当你捡到一块金子、你去告诉你的爸爸、然后你的爸爸就去告诉他的爸爸,也就是你爷爷、然后依次类推,这个过程就叫做事件传播。

事件的常用两种传播方式

  • 事件冒泡 - 由内向外 - 默认
    p -> div -> body -> html -> document -> window

    • (大白话:p就像是一只在白菜心里面的鱼、它想要逃出来,就要从里面一层一层的跑)

    •   var p = document.querySelector('p')
        var div = document.querySelector('div')
        
        //点击p元素事件冒泡
        p.addEventListener('click', function () {
            console.log('我是p元素');
            // 我是p元素
            // 我是div元素
        
        })
        
        //点击div元素事件在最外层,显示一次
        div.addEventListener('click', function () {
            console.log('我是div元素');
            // 我是div元素
        })
      
  • 事件捕获 - 由外向内
    window -> document ->html ->body -> div -> p

    • (大白话:p这条鱼躲在白菜心里,渔民想要抓到他、就要一层一层的拨开白菜)

    •   var p = document.querySelector('p')
        var div = document.querySelector('div')
        
        //点击p元素事件冒泡
        p.addEventListener('click', function () {
            console.log('我是p元素');
            // 我是p元素
            // 我是div元素
        
        })
        
        //点击div元素事件在最外层,显示一次
        div.addEventListener('click', function () {
            console.log('我是div元素');
            // 我是div元素
        })
      

image-20220715232242397

注意事项:addEventListener(事件类型,事件处理函数,事件传播方向(true|false))

事件目标对象

  • target这个属性是事件对象里面的属性、表示你点击的目标。当你触发点击事件的时候、你点击在那个元素上、target就是那个元素。
  • 兼容性----e.target || e.srcElement
p.addEventListener('click', function (e) {
var target = e.target || e.srcElement //事件目标对象
console.log(target);

},false)

阻止事件传播

  • e.stopPropagation() 标准浏览器
  • e.cancelBubble = true ie低版本
  • 兼容性: e.stopPropagation?e.stopPropagation(): e.cancelBubble = true
  • image-20220427194300154
p.addEventListener('click', function (e) {
var target = e.target || e.srcElement //事件目标对象
e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true) //阻止事件传播
console.log(target);

},false)

//点击div元素事件在最外层,显示一次
div.addEventListener('click', function (e) {
var target = e.target || e.srcElement //事件目标对象
e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true) //阻止事件传播
console.log(target);
},false)

事件委托

好处:
  • 减少了事件绑定的数量;对后来动态创建的元素依然有效,解决动态添加的元素节点无法绑定事件的问题;
  • 减少事件的冗余绑定,节约了事件资源。
坏处:
  1. 事件委托基于冒泡,对于不冒泡的事件不支持。
  2. 层级过多,冒泡过程中,可能会被某层阻止掉。
实现事件委托
  • 循环遍历所有元素,给每个元素绑定事件

  • 事件委托给上级元素统一处理**通过事件目标对象区分不同元素

    • 好处:

      1.动态添加元素时, 不用重新绑定事件

  • image-20220427200227887

    <ul>
        <li>张三</li>
        <li>李四</li>
        <li>王麻子</li>
    </ul>
    <script>
        var ul = document.querySelector('ul')
        ul.onclick = function(e){
             e = e || window.event
             target = e.target
            var text = target.innerHTML
            alert(text+'拿快递')
        }
    </script>

十一、ES6新特性

概述:JavaScript的标准——ECMAScript在不断发展,最新版ECMAScript 6标准(简称ES6已经在2015年6月正式发布ES6可以统称2015年后javascript所有最新版本

11.1 let 和 const 关键字

概述:- 我们以前都是使用 var 关键字来声明变量的,- 在 ES6 的时候,多了两个关键字 let 和 const,也是用来声明变量的

let和const共同点

  1. 不允许重复声明变量

    以前var
    var num = 100
    var num = 200//可以
    现在let 
    let num = 100 
    let num = 200//不可以
    
  2. 没有变量提升(没有预解析)

  3. 声明的变量会被所有代码块限制作用范围

    if (1) {
        let num = 100
        console.log(num+'里面');
    }
    console.log(num+"外面");//报错
    

let和const区别

  • let
    1. 声明的变量值可以改变
    2. 声明可以不赋值(渣男)
  • const
    1. 声明的变量值不可以改变
    2. 声明必须赋值(老实人)

11.2 箭头函数

概述:箭头函数是 ES6 里面一个简写函数的语法方式

重点

  1. 箭头函数只能简写函数表达式,不能简写声明式函数image-20220716002256918

语法: (函数的行参) => { 函数体内要执行的代码 }

image-20220716102640284

注意事项

  1. 箭头函数内部没有this、箭头函数的this是上下文的this(重点中的重点)
  2. 形参括号()如形参只有一个的时候可以不写
  3. 函数体大括号{}如只有一行代码的时候、可以不写{}。并且自动return。
  4. 箭头函数不能作为构造函数实例化
  5. 不能使用arguments 实参

11.3 函数传参默认值

概念:我们在定义函数的时候,有的时候需要一个默认值出现。就是当我不传递参数的时候,使用默认值,传递参数了就使用传递的参数。

image-20220716103430050

11.4 解构赋值

概念:ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。

简单对象的结构赋值

  • 注意:
    1. 必须是{}包着的才是对象结构
    2. let {names,age,sex} = obj,里面的名字必须和obj对象里面的属性名对应
let obj = {
    names:'zjf',
    age:18,
    sex:'boy'
}
/* es5写法 */
// let names = obj.names
// let age = obj.age
// let sex = obj.sex

/* es6写法 */
let {names,age,sex} = obj //名字要与里面的属性一样

console.log(names,age,sex);//zjf 18 boy

数组的结构赋值

注意:

  1. 结构数组的个数必须和数组的个数相同
  2. [ ]专门用于解构数组的
const arr = ["张学友", "刘德华", "黎明", "郭富城"];
/* es5写法 */
// let a = arr[0]
// let b = arr[1]
// let c = arr[2]
// let d = arr[3]

/* es6写法 */
let [a,b,c,d] = arr
console.log(a,b,c,d);//张学友 刘德华 黎明 郭富城

复杂对象的解构赋值

可以解构单个对象、但是不可以解构单个数组

//复杂对象的解构赋值
let wangfei = {
    name: "王菲",
    age: 18,
    songs: ["红豆", "流年", "暧昧"],
    history: [
        {name: "窦唯"},
        {name: "李亚鹏"},
        {name: "谢霆锋"}
    ]
};
let {name, age, songs: [one, two, three], history: [first, second, third]} = wangfei;
console.log(name);
console.log(age);
console.log(one);
console.log(two);
console.log(three);
console.log(first);
console.log(second);
console.log(third);

王菲
 18
 红豆
 流年
 暧昧
{name: '窦唯'}
{name: '李亚鹏'}
{name: '谢霆锋'}

交换变量

概念:之前我们交换变量都是需要第三个临时变量来接受和替换。现在解构就实现了不用临时变量就可以交换了。这个有点像python里面的交换变量。

let a = 3;
let b = 4; //交换变量必须加上分号;否则报错

[a,b] = [b,a]
console.log(a,b);

11.5 展开运算符

数组合并 …arr

const arr = [1,2,3,4]
const arr1 = [5,6,7]
let arr2 = [...arr,...arr1] 
console.log(arr2);
//结果:1 2 3 4 5 6 7

对象合并 …obj

const obj = {
name:'jack',
age:18
}

const obj2 = {
...obj,
say:'展开运算符真好用'
}
//可以使用{接受展开对象}然后还是一个对象
console.log({...obj});//age: 18 name: "jack"
console.log(obj2);
// age: 18
// name: "jack"
// say: "展开运算符真好用"

函数传参

image-20220716112615084

11.6 对象字面量简化写法

概念:当属性与值的变量同名时。可以只写一个.

const name = 'jan'
const age = 18
/* es5 */
// const obj = {
//     name:name,
//     age:age
// }

/* es6 */
const obj = {
name,
age
}
console.log(obj);

11.7 js错误处理机制

常见六种错误

  1. SyntaxError
    • SyntaxError对象是解析代码时发生的语法错误。
  2. ReferenceError
    • ReferenceError对象是引用一个不存在的变量时发生的错误。
  3. TypeError
    • TypeError对象是变量或参数不是预期类型时发生的错误。
  4. RangeError
    • RangeError对象是一个值超出有效范围时发生的错误。
    • 主要有几种情况,一是数组长度为负数,二是Number对象的方法参数超出范围,以及函数堆栈超过最大值。

try…catch 结构

提供了try…catch结构,允许对错误进行处理,选择是否往下执行。

捕获错误
try{
//可以发生错误的代码
}catch(e){  e = 生成的错误对象
e
}

十二、JSON

12.1 JSON概述

  • JSON:JavaScript Object Notation(JavaScript 对象标记法),它是一种存储和交换数据的语法。系统创建。
  • 当数据在浏览器与服务器之间进行交换时,这些数据只能是文本,JSON 属于文本并且我们能够把任何 JavaScript 对象转换为 JSON,然后将 JSON 发送到服务器。我们也能把从服务器接收到的任何 JSON 转换为 JavaScript 对象。
  • 我们能够把数据作为 JavaScript 对象来处理,无需复杂的解析和转译。

12.2 JSON语法

注意:

  1. 每一个数据项,都是由一个键值对组成的

  2. 每个键和值必须是字符串、且必须用双引号包围

  3. 键值对的值必须是以下类型中之一

    1. 字符串(在 JSON 中,字符串值必须由双引号编写
    2. 数字
    3. 对象(JSON 对象)
    4. 数组
    5. 布尔
    6. null
    7. Array 数组 []
    8. Object 对象 {}
  4. JSON 的值不可以是以下数据类型之一:

    1. 函数
    2. 日期
    3. undefined

示例:

var person = {"name": "zhangsan", "age": 62, "city": "BeiJing"}; console.log(person);

在这里插入图片描述

12.3 JSON字符串转JS对象

JSON.parse():可以将以JSON字符串转换为JS对象,它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回

示例:

// json字符串
var jsonObj = '{ "name": "Jack", "age": 18, "gender": "男" }'

// 转为js对象的方法
let myObj = JSON.parse(jsonObj)
console.log(myObj);      //{name: 'Jack', age: 18, gender: '男'}
console.log(myObj.name); //Jack

12.4 JS对象转JSON字符串

JSON.stringify():可以将一个JS对象转换为JSON字符串,需要一个js对象作为参数,会返回一个JSON字符串

示例:

var obj = {name: "猪八戒", age: 28, gender: "男"};

let jsonStr = JSON.stringify(obj)
console.log(jsonStr);//{"name":"猪八戒","age":28,"gender":"男"}
console.log(typeof jsonStr);//string

十三、存储的三种方式

13.1 三种的方式的简介

英文名大白话翻译
sessionStorage会话存储
localStorage本地存储
cookie小型文本文件

相同点:

  1. 都保存在浏览器、同源的

不同点:

  1. 数据大小不同
  2. cookie数据不能超过4k

  3. sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

  4. 传递方式不同
    1. cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递
    2. sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存
  5. 数据有效期不同
    1. cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。

    2. sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持

    3. localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据

  6. 作用域不同
    1. cookie是在所有同源窗口中都是共享的。

    2. sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;

    3. localStorage 在所有同源窗口中都是共享的;

13.2 localStorage

image-20220717104100731

概述:html5 中的 Web Storage 存储方式,用于存储一个域名下的需要永久存在在本地的数据,这些数据可以被一直访问,直到这些数据被删除。

应用场景:它主要被用于储存一些不经常改动的,不敏感的数据,比如全国省市区县信息。还可以存储一些不太重要的跟用户相关的数据,

添加键值对

localStorage.setItem(“保存名字符”,“保存对象字符”)

把一个js对象转换为jsonStr字符,再存储

var obj = {name: "猪八戒", age: 28, gender: "男"};
let jsonStr = JSON.stringify(obj)
//添加键值对
localStorage.setItem('user',jsonStr)

image-20220717103551224

获取键值对

localStorage.getItem(‘储存名’)

var obj = {name: "猪八戒", age: 28, gender: "男"};
let jsonStr = JSON.stringify(obj)

// 设置user本地存储
localStorage.setItem('user',jsonStr)
// 获取user本地存储的字符串
let user = localStorage.getItem('user')
// 转换json字符串
let newObj = JSON.parse(user) 


console.log(newObj.name); //猪八戒
console.log(newObj.age);  //28

删除键值对

删除所有

localStorage.clear()

删除单个

localStorage.removeItem('user')

image-20220717103657302

查看键值对个数

console.log(localStorage.length);

13.3 sessionStorage

sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持

用法和localStorage相同

var obj = {name: "猪八戒", age: 28, gender: "男"};
let jsonStr = JSON.stringify(obj)

// 设置user本地存储
sessionStorage.setItem('user',jsonStr)
sessionStorage.setItem('my','word')

// 获取user本地存储的字符串
let user = sessionStorage.getItem('user')
// 转换json字符串
let newObj = JSON.parse(user) 


console.log(newObj.name); //猪八戒
console.log(newObj.age);  //28


// localStorage.removeItem('user')
// localStorage.clear()
console.log(sessionStorage.length);

13.4 cookie

概述:cookie 是一个以字符串的形式存储数据的位置,也可以理解为存储数据的一个区域或者说是空间

特点:

  1. 存储大小有限制、一般是4k左右
  2. 数量有限制、一般是50条左右
  3. 有失效性、有过期事件、一般是会话级别
  4. 有域名限制、谁设置的只有谁能读取

与http协议关系:

  • 每一个 HTTP 请求都会在请求头中携带 cookie 到服务端
  • 每一个 HTTP 响应都会在响应头中携带 cookie 到客户端
  • 也就是说,cookie 是不需要我们手动设置,就会自动在 客户端 和 服务端之间游走的数据
  • 我们只是需要设置一下 cookie 的内容就可以

操作cookie方法

  • 获取cookie :document.cookie
  • 设置cookie
    document.cookie = ‘username=admin’
    document.cookie = ‘username=admin; expires=标准时间’
    document.cookie = ‘username=admin; expires=Thu, 18 Dec 2022 12:00:00 GMT;’
  • 删除cookie
    document.cookie = ‘username=admin; expires=Thu, 18 Dec 2021 12:00:00 GMT;’ 比设置的时间少一秒
  • 后端也可操作cookie
    cookie可以通过http协议在前后端之间传输

cookie的使用

<body>
	<h2>cookie技术</h2>
	<button class="get-cookie">获取</button>
	<button class="save-cookie">保存</button>
	<button class="delete-cookie">删除</button>
	<p></p>

	<script src="./js.cookie.js"></script>
	<script>
		const addCookiKBtn = document.querySelector('.get-cookie')
		const saveCookiKBtn = document.querySelector('.save-cookie')
		const deleteCookiKBtn = document.querySelector('.delete-cookie')
		const pEle = document.querySelector('p')

		//获取cookie
		addCookiKBtn.addEventListener('click', function () {
			let value = Cookies.get('username')
			pEle.innerHTML = value
		})
		//保存cookie
		saveCookiKBtn.addEventListener('click', function () {
			Cookies.set('username', 'jack', { expires: 1 })
			Cookies.set('password', 'jack123', { expires: 1 })
			Cookies.set('age', '20', { expires: 2 })
		})
		//删除cookie
		deleteCookiKBtn.addEventListener('click', function () {
			Cookies.remove('username')
		})
	</script>
</body>

十四、正则表达式

  • 概念:字符串匹配的一种模式

  • 作用:字符串操作

  • 创建正则表达式的两种方式

    • 构造函数方式

      •   const reg = new RegExp('a')
        
    • 字面量方式

      •   const reg2 = /a/
        

正则表达式得方法

test:

  • 概念:匹配成功就返回真,匹配失败就返回假
  • 写法:正则.test(字符串)
  • 返回值:布尔值
let test1 = ()=>{
    let str = 'abcdef'
    let re = /k/ //匹配k字符
    let isOk = re.test(str)
    console.log(isOk?'存在':'不存在'); //不存在
}
test1()

search:

  • 概念:匹配成功就返回索引号,没匹配到就返回-1

  • 写法:字符串.search(正则)

  • 返回值:索引号

  •   let test2 = ()=>{
      let str = 'abcdef'
      let re = /b/
      let index = str.search(re) //匹配方式不一样
      console.log(index); //=>1
      console.log(str.search(/k/));//匹配不到·就返回-1
      }
      test2()
    

match:

  • 概念:匹配成功就返回数组,匹配不成功返回null

  • 写法:字符串.match(正则)

  • 返回值:数组||null

  •   let test3 = ()=>{
          let str="dgfhfgh255554bhku289fgdhdy675"
          let re = /\d+/g; //数字重复多次 全文搜索
          //返回一个数组
          console.log(str.match(re)); //254  289  675
      }
      test3()
    

replace:

  • 概念:匹配成功就替换字符串

  • 写法:字符串.replace(正则,’新字符串’)

  • 返回值:一个新得字符串

  •   let test4 = () =>{
      let str= 'aaa'
      let re = /a/
      str = str.replace(re,'b')
      console.log(str);//输出baa
      }
      test4()
    

常用元字符

\d匹配数字,相当于[0-9]
\D匹配非数字、相当于[ ^ 0-9]
\w匹配字母或数字或汉字或下划线
\W匹配任意不是数字、字母、汉字、下划线得字符
\s匹配任意得空白符、如空格、换行符、制表符等
\S匹配任意不是空白符得字符
.(点号)匹配除了换行符以外得任意字符
[…]匹配方括号中的所有字符
[^…]匹配非方括号中的所有字符

连接符-范围

[0-9]匹配数字、等价于\d
[a-z]匹配英文小写字母
[A-Z]匹配英文大写字母
[0-9a-zA-Z]匹配数字或英文字母

限定符-量词

+重复1次或更多次(必须得有一次)
*重复0次或更多次(任意次数)
重复0次或1次(最多1次)
{n}重复n次
{n,}重复n次或更多次(最少n次)
{n,m}重复n到m次

定位符-边界

^限定开始位置得字符
$限定结尾位置得字符
\b限定单词(字)边界得字符
\B限定非单词(字)边界得字符

优先级顺序

image-20220505190114522

正则工具网站

网址:http://jsrun.net/

网址:https://regexper.com/

十五、对象进阶(面向对象编程)

面向过程编程:解决问题的过程,按步骤进行,第一步做什么,第二步做什么,一步一步完成

面向对象编程:找具有解决问题功能的对象,调用其功能,完成任务。如果对象不存在,则创建对象。

15.1 创建对象的三种方式

new Object

let personObj = new Object()
personObj.name = 'zjf'
personObj.age = 18
personObj.say = function(){
console.log("hello my word");
}
console.log(personObj);//{name: 'zjf', age: 18, say: ƒ}
personObj.say()

字面量方式

let personObj = {
name:'小明',
age:18,
say:function(){
console.log(this.age);
}
}
personObj.say()

工厂函数

大白话:写的是一个函数、返回的是一个对象,这样当你将这个函数赋值给要给变量的时候、这个变量就变相当于实例化了一个对象。只不过这个方法很粗糙

function creatMyFunction(myname,myage){
return{
name:myname,
age:myage,
say:function(){
console.log(this.name,this.age);
}}}

let personObj = creatMyFunction('zjf',18) //接受这个对象
personObj.say() //zjf 18

15.2 构造函数

概述:

  1. 构造函数其实是一种特殊的函数,主要用来初始化对象,也就是为对象成员变量赋初始值,它总与new关键字一起使用。
  2. 对象里面一些公有的属性和方法抽象出来封装到这个函数里面。
  3. 通过一个构造函数创建多个对象,这些对象拥有相同的构造,都可以使用这个构造函数的方法和属性

构造函数的构建

注意:

  1. 构造函数一般==首字母会大写==,为了和普通函数区分

  2. 构造函数的属性和方法前必须加this关键字,指代要生成的对象

  3. new 就是执行构造函数,返回一个对象,不写new就是普通函数的调用,没有创造对象的能力

  4. 构造函数中的this,由于和 new 连用的关系,是指向当前实例对象

function Person(name, age) {
    // 设置对象的属性
    this.name = name;
    this.age = age;
    // 设置对象的方法
    this.sayName = function () {
        console.log(this.name);
    };
}
let Person1 =new Person('zjf',18)
let Person2 =new Person('zjf1',12)
console.log(Person1);//Person {name: 'zjf', age: 18, sayName: ƒ}
console.log(Person2);//Person {name: 'zjf1', age: 12, sayName: ƒ}

总结:

  • 一个构造函数可以通过new创建多个实例对象
  • 创建构造函数时,里面的属性和方法前必须加this
  • 构造函数不需要return 就可以返回结果

构造函数中的return

  1. 不写return正常显示一个对象
  2. return一个简单数据,没有变化,还是一个返回对象
  3. return一个复杂数据、如[ ]结果就为一个数组

构造函数改变函数指向

function Person(name, age=2) {
// 设置对象的属性
this.name = name;
this.age = age;
// 设置对象的方法
this.sayName = function () {
console.log(this.name);
};
}

function Dog(name,age){
this.name = name
console.log(this);//Dog {name: undefined}
Person.call(this,'ww',12) //Dog {name: 'ww', age: 12, sayName: ƒ}
}

let DOG = new Dog()
console.log(DOG);//Dog {name: 'ww', age: 12, sayName: ƒ}
DOG.sayName()

小知识:监测类型

let obj = {
name:'zjf'
}
//对象 instanceof 对象类?
console.log( obj instanceof Object);

点击选项卡的示例

使用面向对象实现一个简单的点击选项卡的示例

image-20220506202728292

css代码部分

* {
    padding: 0;
    margin: 0;
}

ul,
li {
    list-style: none;
}

.container {
    width: 600px;
    margin: 100px auto;
}

.container ul {
    width: 100%;
    height: 50px;
    background-color: pink;
    display: flex;
}

.container ul li {
    width: 200px;
    height: 100%;
    text-align: center;
    line-height: 50px;
    border: 1px solid darkblue;
}

.container ul .active {
    background-color: skyblue;
}

.container ol {
    position: relative;
    width: 100%;
    height: 300px;
    background-color: rgb(187, 187, 168);
    text-align: center;
    line-height: 300px;
    font-size: 20px;
}

.container ol li {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    display: none;
}

.container ol .on {
    display: block;
}

js代码部分

function Tab(id){
            //通过一个root节点 把root下的所有节点都拿到了
            this.root = document.querySelector(id)
            this.uls = this.root.querySelectorAll('ul>li')
            this.ols = this.root.querySelectorAll('ol>li')
            //将this传给that
            let that = this
            //写一个选项卡效果,给这个函数定义一个方法
            //使用this的方法给这个函数定义
            this.onTab =function(){
                //再这个方法里面写所有的点击事件
                for(let i = 0 ; i < this.uls.length; i++){
                    //循环遍历列表数组进行点击事件赋值
                    this.uls[i].onclick = function(){
                        //清除之前所有的选项卡效果
                        that.clear()
                        //给选中的选项卡给样式
                        this.classList.add('active')
                        //通过uls的节点获取到ols节点的属性
                        let index = this.getAttribute('data-index')
                        that.ols[i].classList.add('on')
                    }
                }
            }
            //写一个清除所有的选中效果的
            this.clear = function(){
                for(let i = 0;i < this.uls.length;i++){
                    //清除所有的选项卡的样式
                    this.uls[i].classList.remove('active')
                    //清除所有选项卡区块的样式
                    this.ols[i].classList.remove('on')
                }
            }
        }

        let table =new Tab('#tab1') //new Tab
        table.onTab() //调用方法

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>
    <div class="container" id="tab1">
        <ul>
            <li class="active" data-index="0">选项1</li>
            <li data-index="1">选项2</li>
            <li data-index="2">选项3</li>
        </ul>
        <ol>
            <li class="on">区块1</li>
            <li>区块2</li>
            <li>区块3</li>
        </ol>
    </div>
</body>
</html>

15.3 原型对象

  1. 为什么要用原型对象

    我们学习了构造函数的方式创建对象,你会发现,每一个对象的属性不一样这是一定的,但是它的方法似乎好像是一样的,如果我创建1000个对象,那岂不是内存中就有1000个相同的方法,那要是有10000个,那对内存的浪费可不是一点半点的,我们有没有什么好的办法解决,没错,我们可以把函数抽取出来,作为全局函数, 以了,上代码:

    // 使用构造函数来创建对象
    function Person(name, age) {
        // 设置对象的属性
        this.name = name;
        this.age = age;
        // 设置对象的方法
        this.sayName = sayName
    }
    
    // 抽取方法为全局函数
    function sayName() {
        console.log(this.name);
    }
    
  2. 但是,在全局作用域中定义函数却不是一个好的办法,为什么呢?因为,如果要是涉及到多人协作开发一个项目,别人也有可能叫sayName这个方法,这样在工程合并的时候就会导致一系列的问题,污染全局作用域,那该怎么办呢?有没有一种方法,我只在Person这个类的全局对象中添加一个函数,然后在类中引用?

    // 使用构造函数来创建对象
    function Person(name, age) {
        // 设置对象的属性
        this.name = name;
        this.age = age;
    }
    
    // 在Person类的原型对象中添加方法
    Person.prototype.sayName = function() {
        console.log(this.name);
    };
    

原型对象概念

  1. 我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype,这个属性对应着一个对象,这个对象就是我们所谓的原型对象,即显式原型,原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。

  2. 如果函数作为普通函数调用prototype没有任何作用,当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,我们可以通过__proto__(隐式原型)来访问该属性。当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,如果没有则会去原型对象中寻找,如果找到则直接使用。

  3. 以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了。

原型对象详解

  1. Javascript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象(原型对象prototype)。
  2. 这个原型对象的所有属性和方法,都会被构造函数的实例访问(继承)。
  3. 这也就意味着,我们可以把所有对象实例需要共享的属性和方法直接定义在 prototype 对象上。
image-20220717233012985

15.4 原型链

image-20220717232256852

概念:

  1. prototype是构造函数都有的属性,称为显示原型
  2. ___proto__是每个对象都有的属性,又称为隐式原型。
  3. 但是,___proto__不是一个规范属性,只是部分浏览器实现了此属性,对应的标准属性是[[Prototype]]。

什么是原型链

  1. 当访问一个对象的某个属性或方法时,会先在这个对象本身上查找,
  2. 如果没有找到,则会去它的__proto__([[prototype]])隐式原型上查找,即它的构造函数的prototype
  3. 如果还没有找到就会再在构造函数的prototype的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。

15.5 Class类

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是 一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已,它的一些如下:

  • class:声明类
  • constructor:定义构造函数初始化
  • extends:继承父类
  • super:调用父级构造方法
  • static:定义静态方法和属性
class 类名{
                //类体,
                //构造器
                constructor(){
                    //定义属性                   
                }
                方法(){

                }
            }
/父类
class Phone {
    //构造方法
    constructor(brand, color, price) {
        this.brand = brand;
        this.color = color;
        this.price = price;
    }

    //对象方法
    call() {
        console.log("我可以打电话!!!")
    }
}

//子类
class SmartPhone extends Phone {
    constructor(brand, color, price, screen, pixel) {
        super(brand, color, price);
        this.screen = screen;
        this.pixel = pixel;
    }

    //子类方法
    photo() {
        console.log("我可以拍照!!");
    }

    playGame() {
        console.log("我可以玩游戏!!");
    }

    //方法重写
    call() {
        console.log("我可以进行视频通话!!");
    }

    //静态方法
    static run() {
        console.log("我可以运行程序")
    }

    static connect() {
        console.log("我可以建立连接")
    }
}

//实例化对象
const Nokia = new Phone("诺基亚", "灰色", 230);
const iPhone6s = new SmartPhone("苹果", "白色", 6088, "4.7inch", "500w");
//调用子类方法
iPhone6s.playGame();
//调用重写方法
iPhone6s.call();
//调用静态方法
SmartPhone.run();
在这里插入图片描述

十六、网络编程

16.1 介绍网络编程

  1. 为什么要学Nodejs:

    目前公司大部分的前端人员、都要多多少少要会一门后端语言、这样做的原因不仅仅是因为可以更加方便你和后端人员吵架,哦不对是沟通。还能拓宽你未来的成长道路、让你成为一个全栈工程师。

  2. 后端是什么:

    后端接收请求处理业务逻辑响应数据需要写代码来实现,需要一门编程语言,后端编程语言java、javascript、python、php…

    编写的代码部署到一台独立的电脑,供用户访问,这台电脑称为后端服务器。

  3. 服务器是怎样访问的?

    ip地址唯一标识网络中一台电脑
    port端口号标识电脑中不同应用程序
    域名解决ip地址不好记的问题。域名与ip地址一一对应,通过域名解析服务器DNS进行解析
    数据传输协议限制用户和服务器之间交流传输数据的方式和规则
    规则:
    -建立连接通道
    -相互通信
    -关闭连接通道
    常见的传输协议是 http 和 https
    区别:
    -http 是一种常见协议,不是很安全
    -https 是一种加密传输协议
    url地址统一资源定位符,标识网络中资源数据
    url地址格式协议://域名:端口/资源
  4. 前端与后端传输数据图例:

    image-20220720095410800

16.2 数据库

数据库:以二维表形式存储数据的仓库
数据管理软件:oracle,sqlserver,db2,mysql,java

SQL语句介绍

  • SQL:结构化查询语言,专门操作数据库的一门语言
  • SQL语句:查询语句,查询数据库表记录的语句

mysql语句

  • 插入记录

    INSERT INTO 表名 (字段名1,字段名2,字段名3…)VALUES(值1,值2,值3…)

    INSERT INTO product(id,name,price,num) VALUES(1004,'vaue框架',999.9,1)
    
  • 修改记录

    UPDATE product SET price = 199.89 WHERE id = 1001 
    
  • 删除记录

    DELETE FROM product WHERE id = 1005
    
  • 查询记录

    SELECT 字段名1,字段名2,字段名3

    FROM 表名

    WHERE 条件

     select id,name,price,num from product where id=1001
     SELECT  id,price,name from product WHERE id = 1001
    
#SELECT name FROM product
#插入数据
#INSERT INTO product(id,name,price,num) VALUES(1004,'vaue框架',999.9,1)


#修改刚才添加得数据
#UPDATE product SET price = 199.89 WHERE id = 1001 

#删除数据
#DELETE FROM product WHERE id = 1005

#查询数据
SELECT  id,price,name from product WHERE id = 1001

mysql第三方模块

node.js后端程序连接数据库,执行sql语句。

npm install mysql //下载mysql第三方模块

12.4.1 操作数据库

  • 引入mysql
  • 创建连接对象
  • 执行sql语句
  • 关闭连接

mysql第三方包下载网址: https://www.npmjs.com/package/mysql

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端达闻西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值