JavaScript 是一种脚本编程语言,这门语言可用于 HTML 和 web,更可广泛用于服务器、PC、笔记本电脑、平板电脑和智能手机等设备。它可以在网页上实现复杂的功能,网页展现给你的不再是简单的静态信息,而是实时的内容更新。

1.书写语法

1.注释

单行注释 : // 注释内容

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

2.代码块

{}

2.输出语句

window.alter()写入警告框

document.write()写入HTML输出

console.log()写入浏览器控制台

1.window.alter();

2.document.write();

3.console.log();

输入语句

括号里的为提示内容

prompt(“输入”)

4.模板字符串

语法

使用``

在拼接内容时用${}包住格式化输出的内容

3.变量

1.var关键字

  • 变量可以存放不同类型的值
  • 可以重复定义

2.let关键字

  • 只在let关键字所在的代码块生效
  • 不可以重复定义

3.const关键字(优先)

  • 常量不允许修改

4.数据类型

1.原始数据类型和引用类型

  • number 数字
  • string 字符串
  • boolean 布尔,true,false
  • null 对象为空
  • undefined:当声明变量未初始化时

2.使用typeof运算符可以获取数据类型

typeof x

typeof(x)

5.运算符(大多与java类似)

1.== 和 ===

== 会进行类型转换,===不会进行类型转换

逻辑运算符|| 和&& 会发生逻辑阻断,即只要前面的不满足就停止后面式子的计算

6.类型转换

+自动转成数字型

var h = parseInt(time / 60 / 60 % 24); 转成整数

parseInt()

parseFloat()

如果将字符串的字面值转为数字,如果不是数字就为NAN (not a number)

“123N” -> 123

“N123” -> NAN

7.函数

1.定义

使用function关键字定义

  • 实参不需要填类型
  • 返回值也不用定义类型
//1
function functionname(参数1 , 参数2)
{
    //参数执行的代码
}
//2
var funtion = function(参数1,参数2...){

	//参数执行的代码

}
//3
var add = function(a,b){

	return a+b;

}

2.匿名函数

let num = function(x,y){
    return x+y;
}(1,2);
alert(num);

立即执行函数

避免函数之间相互污染

两种写法

(function(){console.log("1");})();
(function(){
    let number=20;
    console.log(number);
    })();

(function(){}());

(function(x,y){
    console.log(x+y);}(1,2));

(function getnumber(x,y){
    console.log(x+y);}(1,2));

本质就是调用匿名函数

3.调用

函数名称(实际参数列表)

  • 可以多传,但是只会接收对应的参数

4.回调函数

如果将函数A作为参数传递给函数B是,我们称A为回调函数

function fn() {

​ console.log(‘我是回调函数…’)

}

SetInterval(fn,1000);

4.间歇函数

setInterval(函数,时间(毫秒))

setInterval(function(){},1000)

<script>
        function fn(){
            alert("1");
        }
        setInterval(fn,1000);
</script>

3.关闭定时器

setInterval()函数的返回值为一个整数,表示标号

clearInterval

<script>
        function fn(){
            alert("1");
        }

        let n = setInterval(fn,1000);
        clearInterval(n);
</script>

8.Array

用于定义数组

1.定义Array

var 变量名 = new Array(元素列表);

var 变量名 = [元素列表];

2.索引访问

arr[索引] = 值;

3.属性

length 长度(元素数量)

4.方法

foreach()遍历

test.forEach(ele => {
    console.log(ele);
});

push()将新的元素增加到列表的末尾,并增加列表的长度

test.push(null);

splice()删除元素

test.splice(0,3)

第一个参数:开始位置

第二个参数:截取长度

3.常见方法

1.forEach()

map()

filter()过滤数组

返回新数组,返回的是筛选满足条件的数组元素

reduce 返回累计处理的结果

arr.reduce(function(){},起始值)

arr.reduce(function(上一次值,当前值){},起始值)

arr = [1,8,9];
const total = arr.reduce(function(pre,current){
    return pre+current;
});
console.log(total);
const total1 = arr.reduce(function(pre,current){
    return pre+current;
},10);
console.log(total1);

如果没有起始值,则上一次以数组的第一个元素的值

每一次循环,把返回值给作为下一次循环的上一次值

如果有起始值,则起始值为上一次值

9.String

String字符串对象创建方式有两种:

var 变量名=new String(“……”);//方式一

var str = new String(“Hello String”);

var 变量名=“”;//方式二

var str = “Hello String”;

var str = ‘Hello String’;

属性

length 字符串的长度。

方法

charAt() 返回在指定位置的字符。

indexof() 检索字符串。

trim() 去除字符串两边的空格

substring() 提取字符串中两个指定的索引号之间的字符

10.JS对象

1.定义

1.var 对象名 = {

​ 属性名 : 属性值,

​ 属性名 : 属性值,

​ 属性名 : 属性值,

​ 属性名 : 属性值,

​ 函数名称 : function(形参列表){}

};

2.const obj =new Object()

2.调用

对象名.属性名;

对象名.方法名();

var test = {
    name : "Tom",
    age : 20,
    gender : "male",
    sleep : function()
    {
        alert("test.gender");
    }
}

window.alert(test.name);
window.alert(test.sleep());

另一种写法

var test = {
    name : "Tom",
    age : 20,
    gender : "male",
/*     sleep : function()
    {
        alert("test.gender");
    } */
    sleep()
    {
        alter("test.gender");
    }
}

window.alert(test.name);
window.alert(test.sleep());

3.增删操作

对象名.不存在的属性值 会创建该属性值

delete 属性值

4.访问属性的两种方法

对象名[属性值]

console.log(obj["goods"]);

里面的属性值一定要加引号

5.遍历对象

遍历输出对象的元素

<script>
    let obj = {
        "goods" : "richu",
        "weight" : 50,
        user : "123"
    }
    console.log(obj["goods"]);
    for (let i in obj){
        console.log(i+"->"+obj[i]);
    }
</script>

6.内置对象

1.Math

Math.PI

圆周率,一个圆的周长和直径之比,约等于 3.14159

Math.abs(x)

返回一个数的绝对值。

Math.floor(x)

向下取整

Math.ceil(x)

向上取整

Math.round(x)

四舍五入

ParseInt()

取整函数

随机数

Math.random()

返回一个0-1之间的数字[0~1]

<script>
        let a=parseInt(prompt("输入"));
        let b=parseInt(prompt("输入"));
        if (a > b){
            let res = Math.floor(Math.random()*(a-b+1)+b);
            alert(res);
        }
        else{
            let res = Math.floor(Math.random()*(b-a+1))+a;
            alert(res);
        }
    </script>

2.时间对象

new Date()

div.innerHTML=date.toLocaleString();
div.innerHTML=date.toLocaleDateString();

getFullYear() 获得年份 获取四位年份

getMonth() 获得月份 取值为0~11

getDate() 获取月份中的每一天 不同月份取值也不相同

getDay() 获取星期 取值为0~6

getHours() 获取小时 取值为0~23

getMinutes() 获取分钟 取值为0~59

getSeconds() 获取秒 取值为0~59

获取时间戳的方式

date.getTime()

+new Date()

Date.now()

案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <span class="hour"></span>
        <span class="mintues"></span>
        <span class="second"></span>
    </div>
    <script>
        const hour = document.querySelector(".hour");
        const mintues = document.querySelector(".mintues");
        const sec = document.querySelector(".second");

        hour.innerHTML=h;
        mintues.innerHTML=m;
        sec.innerHTML=s;
        function fn(){
            const now = +new Date();
            const last = +new Date("2024-6-9 19:20:00");

            const second = (last-now)/1000

            let h = parseInt(second/60/60/24);
            h=h<10?'0'+h:h;
            let m = parseInt(second / 60 % 60);
            m=m<10?'0'+m:m;
            let s=parseInt(second%60);
            s=s<10?'0'+s:s;

            /* console.log(h,m,s); */

            const hour = document.querySelector(".hour");
            const mintues = document.querySelector(".mintues");
            const sec = document.querySelector(".second");

            hour.innerHTML=h;
            mintues.innerHTML=m;
            sec.innerHTML=s;
        }

        setInterval(fn,1000);
    </script>
</body>
</html>

7.构造函数

用来初始化对象

命名以大写字母开头

只能由new操作符来执行

不需要写return

function Name(uname,age) {
    this.uname=uname;
    this.age=age
}

8.实例化执行过程

1.创建新对象

2.构造函数this指向新对象

3.执行构造函数,修改this,添加新的属性

4.返回新对象

9.实例成员和静态成员

通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员

为构造函数传入参数,创建解构相同但值不同的对象

构造函数创建的实例对象彼此独立互不影响

构造函数的属性和方法被称为静态成员(静态属性和静态方法)

10.Object

1.获取对象中的所有键

const o={name:'1',age:18};
const arr=Object.keys(o);
console.log(arr);

返回的是一个数组

2.获得对象的所有属性值

const o={name:'1',age:18};
const arr =Object.values(o);

返回的是一个数组

3.拷贝

Object.assign(o,oo);

可以追加对象的一个新属性

11.JSON格式

概念:Javascript Object Notation,JavaScript对象标记法

JSON 是通过JavaScript对象标记法书写的文本

用于网络数据传输

‘{

​ “name” = “123”

}’

key必须使用双引号括起来

value的数据类型为:

  • 数字
  • 字符串
  • 逻辑值
  • 数组
  • 对象
  • null

将JSON字符串转为JS对象

var jsObject = JSON.parse(userStr);

将JS对象转为JSON字符串

var jsonStr = JSON.stringify(jsObject);

12.BOM

1.Window

浏览器窗口对象

  • 属性

    history

    location

    navigator

  • 方法

    alert()

    alert("asd")

    confirm()

    confirm("确认")

    setInterval();按照指定的周期来调用函数或表达式

    setTimeout();在指定毫秒数后调用函数或计算表达式

setInterval(function()
{
    var i =0;
    console.log("d" + i);
    i++;
},2000);

setTimeout(function()
{
    console.log("1");
},3000)

2.location

location

  • 介绍

地址栏对象

  • 获取

location.属性

  • 属性

herf:设置或返回完整的URL

search:请求后面(?后面的内容)

hash获取地址中的hash值,符号#后面部分

reload刷新页面

alert(location.href);

location.href="https://www.baidu.com";
//修改地址栏,自动跳转
const bt = document.querySelector("button");

bt.addEventListener('click',function()
                    {
    location.reload(true);
    //true 为强制刷新
})

3.navigator对象

4.history对象

主要管理历史记录

back() 后退功能

forward() 前进功能

go(参数)

go(1) =forward()

go(-1)=back()

5.延迟函数

JavaScript 内置的一个用来让代码延迟执行的函数,叫setTimeout

setTimeout(回调函数,等待的毫秒数)

setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行,平时省略window

清除延时函数:

let timer = setTimeout(回调函数,等待的毫秒数)

clearTimeout(timer)

延时器需要等待,所以后面的代码先执行

每一次调用延时器都会产生一个新的延时器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <a href="#">跳转</a>
    <script>
        const a = document.querySelector("a");
        let s=5;
        const num = setInterval(function()
        {
            s--;
            a.innerHTML=`${s}后跳转`;
            if (s===0)
            {
                clearInterval(num);
                location.href="https://www.jd.com";
            }
    },1000)
    </script>
</body>
</html>

6.本地存储

随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案

1、数据存储在用户浏览器中

2、设置、读取方便、甚至页面刷新不丢失数据

3、容量较大,sessionStorage和localStorage约5M左右

作用:可以将数据永久存储在本地(用户的电脑),除非手动删除,否则关闭页面也会存在

特性:

可以多窗口(页面)共享(同一浏览器可以共享)

以键值对的形式存储使用

1.存储的方式

localStorage.setItem(‘uname’,’name’)

localStorage.setItem(建,值)

2.获取的方式

localStorage.getItem(‘uname’)

localStorage.getItem(键)

3.删除本地存储

localStorage.remove(‘uname’)

localStorage.remove(键)

4.更改

localStorage.setItem(‘uname’,’newname’)

localStorage.setItem(键,新值)

7.sessionStorage

特性:

生命周期为关闭浏览器窗口

在同一个窗口(页面)下数据可以共享

以键值对的形式存储使用

用法跟localStorage基本相同

8.本地存储复杂数据类型

用于渲染(刷新不会丢失)

复杂数据类型存储必须转换成JSON数据格式

JSON.stringify()

const obj={
    name : '1',
    age: 18,
    adress:"sh"
}
localStorage.setItem('obj',JSON.stringify(obj));
console.log(localStorage.getItem('obj'));

把JSON对象转换成字符串

JSON.parse()

案例

const arr = JSON.parse(localStorage.getItem(‘data’)) || [];

9.数组map 方法

使用场景:

map 可以遍历数组处理数据,并且返回新的数组

语法:

<body>
  <script>
  const arr = ['red', 'blue', 'pink']
  // 1. 数组 map方法 处理数据并且 返回一个数组
   const newArr = arr.map(function (ele, index) {
    // console.log(ele)  // 数组元素
    // console.log(index) // 索引号
    return ele + '颜色'
	})
	console.log(newArr)
</script>
</body>

map 也称为映射。映射是个术语,指两个元素的集之间元素相互“对应”的关系。

map重点在于有返回值,forEach没有返回值(undefined)

10.数组join方法

作用:join() 方法用于把数组中的所有元素转换一个字符串

语法:

<body>
  <script>
    const arr = ['red', 'blue', 'pink']

    // 1. 数组 map方法 处理数据并且 返回一个数组
    const newArr = arr.map(function (ele, index) {
      // console.log(ele)  // 数组元素
      // console.log(index) // 索引号
      return ele + '颜色'
    })
    console.log(newArr)

    // 2. 数组join方法  把数组转换为字符串
    // 小括号为空则逗号分割
    console.log(newArr.join())  // red颜色,blue颜色,pink颜色
    // 小括号是空字符串,则元素之间没有分隔符
    console.log(newArr.join(''))  //red颜色blue颜色pink颜色
    console.log(newArr.join('|'))  //red颜色|blue颜色|pink颜色
  </script>
</body>

11.正则表达式

正则表达式(Regular Expression)是一种字符串匹配的模式(规则)

使用场景:

  • 例如验证表单:手机号表单要求用户只能输入11位的数字 (匹配)
  • 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等

1.正则基本使用

  1. 定义规则

    const reg =  /表达式/
    • 其中/ /是正则表达式字面量
    • 正则表达式也是对象
  2. 使用正则

    • test()方法 用来查看正则表达式与指定的字符串是否匹配
    • 如果正则表达式与指定的字符串匹配 ,返回true,否则false
<body>
  <script>
    // 正则表达式的基本使用
    const str = 'web前端开发'
    // 1. 定义规则
    const reg = /web/

    // 2. 使用正则  test()
    console.log(reg.test(str))  // true  如果符合规则匹配上则返回true
    console.log(reg.test('java开发'))  // false  如果不符合规则匹配上则返回 false
  </script>
</body>

2.元字符

  1. 普通字符:
  • 大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。
  • 普通字符只能够匹配字符串中与它们相同的字符。
  • 比如,规定用户只能输入英文26个英文字母,普通字符的话 /[abcdefghijklmnopqrstuvwxyz]/
  1. 元字符(特殊字符)
  • 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
  • 比如,规定用户只能输入英文26个英文字母,换成元字符写法: /[a-z]/

3.边界符

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符

如果 ^ 和 $ 在一起,表示必须是精确匹配

<body>
  <script>
    // 元字符之边界符
    // 1. 匹配开头的位置 ^
    const reg = /^web/
    console.log(reg.test('web前端'))  // true
    console.log(reg.test('前端web'))  // false
    console.log(reg.test('前端web学习'))  // false
    console.log(reg.test('we'))  // false

    // 2. 匹配结束的位置 $
    const reg1 = /web$/
    console.log(reg1.test('web前端'))  //  false
    console.log(reg1.test('前端web'))  // true
    console.log(reg1.test('前端web学习'))  // false
    console.log(reg1.test('we'))  // false  

    // 3. 精确匹配 ^ $
    const reg2 = /^web$/
    console.log(reg2.test('web前端'))  //  false
    console.log(reg2.test('前端web'))  // false
    console.log(reg2.test('前端web学习'))  // false
    console.log(reg2.test('we'))  // false 
    console.log(reg2.test('web'))  // true
    console.log(reg2.test('webweb'))  // flase 
  </script>
</body>

4.量词

量词用来设定某个模式重复次数

注意: 逗号左右两侧千万不要出现空格

<body>
  <script>
    // 元字符之量词
    // 1. * 重复次数 >= 0 次
    const reg1 = /^w*$/
    console.log(reg1.test(''))  // true
    console.log(reg1.test('w'))  // true
    console.log(reg1.test('ww'))  // true
    console.log('-----------------------')

    // 2. + 重复次数 >= 1 次
    const reg2 = /^w+$/
    console.log(reg2.test(''))  // false
    console.log(reg2.test('w'))  // true
    console.log(reg2.test('ww'))  // true
    console.log('-----------------------')

    // 3. ? 重复次数  0 || 1 
    const reg3 = /^w?$/
    console.log(reg3.test(''))  // true
    console.log(reg3.test('w'))  // true
    console.log(reg3.test('ww'))  // false
    console.log('-----------------------')


    // 4. {n} 重复 n 次
    const reg4 = /^w{3}$/
    console.log(reg4.test(''))  // false
    console.log(reg4.test('w'))  // flase
    console.log(reg4.test('ww'))  // false
    console.log(reg4.test('www'))  // true
    console.log(reg4.test('wwww'))  // false
    console.log('-----------------------')

    // 5. {n,} 重复次数 >= n 
    const reg5 = /^w{2,}$/
    console.log(reg5.test(''))  // false
    console.log(reg5.test('w'))  // false
    console.log(reg5.test('ww'))  // true
    console.log(reg5.test('www'))  // true
    console.log('-----------------------')

    // 6. {n,m}   n =< 重复次数 <= m
    const reg6 = /^w{2,4}$/
    console.log(reg6.test('w'))  // false
    console.log(reg6.test('ww'))  // true
    console.log(reg6.test('www'))  // true
    console.log(reg6.test('wwww'))  // true
    console.log(reg6.test('wwwww'))  // false

    // 7. 注意事项: 逗号两侧千万不要加空格否则会匹配失败

  </script>

5.范围

表示字符的范围,定义的规则限定在某个范围,比如只能是英文字母,或者数字等等,用表示范围

<body>
  <script>
    // 元字符之范围  []  
    // 1. [abc] 匹配包含的单个字符, 多选1
    const reg1 = /^[abc]$/
    console.log(reg1.test('a'))  // true
    console.log(reg1.test('b'))  // true
    console.log(reg1.test('c'))  // true
    console.log(reg1.test('d'))  // false
    console.log(reg1.test('ab'))  // false

    // 2. [a-z] 连字符 单个
    const reg2 = /^[a-z]$/
    console.log(reg2.test('a'))  // true
    console.log(reg2.test('p'))  // true
    console.log(reg2.test('0'))  // false
    console.log(reg2.test('A'))  // false
    // 想要包含小写字母,大写字母 ,数字
    const reg3 = /^[a-zA-Z0-9]$/
    console.log(reg3.test('B'))  // true
    console.log(reg3.test('b'))  // true
    console.log(reg3.test(9))  // true
    console.log(reg3.test(','))  // flase

    // 用户名可以输入英文字母,数字,可以加下划线,要求 6~16位
    const reg4 = /^[a-zA-Z0-9_]{6,16}$/
    console.log(reg4.test('abcd1'))  // false 
    console.log(reg4.test('abcd12'))  // true
    console.log(reg4.test('ABcd12'))  // true
    console.log(reg4.test('ABcd12_'))  // true

    // 3. [^a-z] 取反符
    const reg5 = /^[^a-z]$/
    console.log(reg5.test('a'))  // false 
    console.log(reg5.test('A'))  // true
    console.log(reg5.test(8))  // true

  </script>
</body>

6.字符类

某些常见模式的简写方式,区分字母和数字

\d 0-9数字

\D 非0-9的数字

\w 字母数字和下划线

\W 非字母数字和下划线

\s 空格

\S 非空格

7.替换和修饰符

replace 替换方法,可以完成字符的替换

<body>
  <script>
    // 替换和修饰符
    const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'
    // 1. 替换  replace  需求:把前端替换为 web
    // 1.1 replace 返回值是替换完毕的字符串
    // const strEnd = str.replace(/前端/, 'web') 只能替换一个
  </script>
</body>

修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等

  • i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
  • g 是单词 global 的缩写,匹配所有满足正则表达式的结果
<body>
  <script>
    // 替换和修饰符
    const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'
    // 1. 替换  replace  需求:把前端替换为 web
    // 1.1 replace 返回值是替换完毕的字符串
    // const strEnd = str.replace(/前端/, 'web') 只能替换一个

    // 2. 修饰符 g 全部替换
    const strEnd = str.replace(/前端/g, 'web')
    console.log(strEnd) 
  </script>
</body>

8.案例

1.验证码

const code= document.querySelector('.code');
var falg = true;
code.addEventListener('click',function(){
    if (falg)
    {
        falg=false;
        let tm = 6;
        let i =setInterval(function(){
            tm--;
            code.innerHTML = `0${tm}后重新获取`;
            if (tm==0)
            {
                clearInterval(i);
                code.innerHTML = "重新获取";
                falg=true;
            }
        },1000)
        }
})

12.change 事件

给input注册 change 事件,值被修改并且失去焦点后触发

13.判断是否有类

元素.classList.contains() 看看有没有包含某个类,如果有则返回true,么有则返回false

13.DOM

1.简介

Document Object Model 文档对象模型

是用来呈现以及与任意HTMl或XML文档交互的API

  • 作用:开发网页内容特效和实现用户交互

2.DOM树

文档树直观的体现了标签与标签之间的关系

pkkW6MV.png

3.DOM对象

  • document 整个文档对象
  • Element 元素对象
  • Attribute 属性对象
  • Text 文本对象
  • comment 注释对象

HTML中的Element对象可以通过Document对象获取,而Document对象是通过window对象获取的。

  • 根据id属性,返回Element对象

var h1 = document.getElementById(‘h1’);

  • 根据标签名称获取,返回Element对象数组

var divs = document.getElementsByTagName(‘div’);

  • 根据name属性值获取,返回Element对象数组

var hobbys = document.getElementsByname(‘hobby’);

  • 根据Class属性值获取,返回Element对象数组

var class = document.getElementsByClassName(‘cls’);

4.获取DOM对象

1.获取匹配的第一个元素

document.querySelector(CSS选择器)

返回值为CSS选择器匹配的第一个元素,一个HTMLElement对象

如果没匹配到返回null

<body>
    <p id="nav">导航</p>
    <script>
        const nav = document.querySelector("#nav");
        console.log(nav);
        nav.style.color = "red";
    </script>
</body>

2.选择所有匹配的元素,返回数组(伪数组)

document.querySelectorAll(CSS选择器)

伪数组

  • 有长度,有索引号
  • 没有push和pop

遍历伪数组

<body>
    <ul id="nav">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        const lis = document.querySelectorAll("#nav li");
        for (let i=0;i<lis.length;i++)
        {
            console.log(lis[i]);
        }
    </script>

3.其他获取方式

document.getElementById();

根据ID

document.getElementsByTagName();

根据标签名

document.getElementsByClassName();

根据类名

5.操作元素对象

innerText

不解析文本标签

<div class="box">内容</div>
  <script>
      const box = document.querySelector(".box");
      console.log(box.innerText);
      box.innerText = "<strong>我是盒子</strong>";
  </script>

解析文本标签

innerHTML

<div class="box">内容</div>
    <script>
        const box = document.querySelector(".box");
        box.innerHTML = "<strong>我是盒子</strong>";
    </script>

6.通过style修改样式属性

对象名.style = 值

    <style>
        #c{
            width: 200px;
            height: 200px;
            background-color: pink;
        }
    </style>



<body>
    <div id="c">触发浏览器中的行为</div>
    <script>
        const divs = document.querySelector("#c");
        divs.style.backgroundColor = 'red';
        divs.style.border="2px solid blue"
        //divs.style.fontFamily="楷体";
        divs.style.fontFamily="隶书";
    </script>
</body>

7.通过类名修改样式

添加类名

类名.className = ‘类名’;

    <style>
        div{
            height: 200px;
            width: 200px;
            background-color:skyblue ;
        }
        .box{
            height: 400px;
            width: 400px;
            background-color: red;
        }
    </style>



<body>
    <div></div>
    <script>
        const box = document.querySelector("div");
        box.className='box';
    </script>
</body>

用新值替换旧值

8.通过classList修改样式 (最终解决方案)

增加类名

类名.classList.add()

移除类名

类名.classList.remove

切换类

类名.classList.toggle()

有就删掉 没有就加上

9.操作表单元素属性

获取DOM对象.属性名

DOM对象.属性名 = 新值

表单属性中添加就有效果,移除就没有效果,一律使用布尔值表示如果为true代表添加了该属性 如果是false代表移除了该属性

比如:disabled、checked、selected

10.自定义属性

必须以data-开头

一律以dataset对象方式来获取

类名.dataset.自定义属性(不加data-)

11.查找DOM节点

1.父节点查找

parentNode属性

子元素.parentNode

const baby = document.querySelector(".baby");
console.log(baby.parentNode);

2.子节点查找

children

3.兄弟节点

ul.previousElementSibling /* 上一个兄弟 */
ul.nextElementSibling   /* 下一个兄弟 */

12.创建新节点

1.创建

document.createElement(‘div’);

2.追加

appendChild()

父元素.appendChild(节点)

从后面追加

3.插入

insertBefore()

在前面插入

父元素.insertBefore(要插入的元素,在哪个元素前面)

13.克隆节点

cloneNode(true)

false只克隆标签

14删除节点

如果不存在父子关系则删除不成功

removeChild()

14.事务

HTML事件可以触发浏览器中的行为,比方说当用户点击某个 HTML 元素时启动一段 JavaScript。

1.两种事件绑定方式(不推荐)

DOM L0

<body>
    <input type="button" value="按钮1" id="btn1" onclick="on()">
    <input type="button" value="按钮2" id="btn2" onclick="on()">
</body>

<script>
    function on()
    {
        alert("hahaha");
    }

    document.getElementById("btn2").onclick= function() {
        alert("hehehehe");
    }
</script>

推荐使用事件监听

2.常见事件

1.窗口事件

由窗口触发该事件 (同样适用于 标签):

属性 描述

onblur 当窗口失去焦点时运行脚本。

onfocus 当窗口获得焦点时运行脚本。

onload 当文档加载之后运行脚本。

onresize 当调整窗口大小时运行脚本。

onstorage 当 Web Storage 区域更新时(存储空间中的数据发生变化时)运行脚本。

onkeydown 键盘被按下

onmouseover 鼠标移入

onmouseout 鼠标移出

2.表单事件

表单事件在HTML表单中触发 (适用于所有 HTML 元素,但该HTML元素需在form表单内):

属性 描述

onblur 当元素失去焦点时运行脚本。

onfocus 当元素获得焦点时运行脚本。

onchange 当元素改变时运行脚本。

oninput 当元素获得用户输入时运行脚本。

oninvalid 当元素无效时运行脚本。

onselect 当选取元素时运行脚本。

onsubmit 当提交表单时运行脚本。

3.键盘事件

通过键盘触发事件,类似用户的行为:

属性 描述
onkeydown 当按下按键时运行脚本。
onkeyup 当松开按键时运行脚本。
onkeypress 当按下并松开按键时运行脚本。

键鼠属性:

属性 描述
ctrlKey 返回当事件被触发时,“CTRL” 键是否被按下

altKey 返回当事件被触发时,“ALT” 是否被按下

shiftKey 返回当事件被触发时,“SHIFT” 键是否被按下

clientX 返回当事件被触发时,鼠标指针的水平坐标

clientY 返回当事件被触发时,鼠标指针的垂直坐标

screenX 返回当某个事件被触发时,鼠标指针的水平坐标

screenY 返回当某个事件被触发时,鼠标指针的垂直坐标

4.鼠标事件

通过鼠标触发事件,类似用户的行为:

属性 描述
onclick 当单击鼠标时运行脚本

ondblclick 当双击鼠标时运行脚本

onmousedown 当按下鼠标按钮时运行脚本

onmouseup 当松开鼠标按钮时运行脚本

onmousemove 当鼠标指针移动时运行脚本

onmouseover 当鼠标指针移至元素之上时运行脚本,不可以阻止冒泡

onmouseout 当鼠标指针移出元素时运行脚本,不可以阻止冒泡

onmouseenter 当鼠标指针移至元素之上时运行脚本,可以阻止冒泡

onmouseleave 当鼠标指针移出元素时运行脚本,可以阻止冒泡

onmousewheel 当转动鼠标滚轮时运行脚本

onscroll 当滚动元素的滚动条时运行脚本

5.媒体事件

通过视频(videos),图像(images)或音频(audio) 触发该事件

属性 描述
onabort 当发生中止事件时运行脚本

oncanplay 当媒介能够开始播放但可能因缓冲而需要停止时运行脚本

oncanplaythrough 当媒介能够无需因缓冲而停止即可播放至结尾时运行脚本

ondurationchange 当媒介长度改变时运行脚本

onemptied 当媒介资源元素突然为空时(网络错误、加载错误等)运行脚本

onended 当媒介已抵达结尾时运行脚本

onerror 当在元素加载期间发生错误时运行脚本

onloadeddata 当加载媒介数据时运行脚本

onloadedmetadata 当媒介元素的持续时间以及其它媒介数据已加载时运行脚本

onloadstart 当浏览器开始加载媒介数据时运行脚本

onpause 当媒介数据暂停时运行脚本

onplay 当媒介数据将要开始播放时运行脚本

onplaying 当媒介数据已开始播放时运行脚本

onprogress 当浏览器正在取媒介数据时运行脚本

onratechange 当媒介数据的播放速率改变时运行脚本

onreadystatechange 当就绪状态(ready-state)改变时运行脚本

onseeked 当媒介元素的定位属性不再为真且定位已结束时运行脚本

onseeking 当媒介元素的定位属性为真且定位已开始时运行脚本

onstalled 当取回媒介数据过程中(延迟)存在错误时运行脚本

onsuspend 当浏览器已在取媒介数据但在取回整个媒介文件之前停止时运行脚本

ontimeupdate 当媒介改变其播放位置时运行脚本

onvolumechange 当媒介改变音量亦或当音量被设置为静音时运行脚本

onwaiting 当媒介已停止播放但打算继续播放时运行脚本

5.其它事件

属性 描述
onshow 元素在上下文显示时触发。
ontoggle 当用户打开或关闭
元素时触发。

6.事件冒泡

事件的冒泡(Bubble):所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发,在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡。

3.事件监听

DOM L2

能够给DOM元素添加事件监听

元素对象addEventListener(‘事件类型’,要执行的函数)

  • 事件源:获取DOM元素
  • 事件类型:用什么方式触发,鼠标单击click,鼠标经过mouseover等
  • 事件调用的函数:要做什么事情
<button>点击</button>
<script>
    const btn = document.querySelector("button");

    btn.addEventListener('click',function(){
        alert("Hello");
    })
</script>

4.事件

1.鼠标事件

1.click 鼠标点击

2.moseenter 鼠标经过

3.moseleave 鼠标离开

2.焦点事件

foucs 获得焦点

blur 失去焦点

3.键盘事件

keydown 键盘按下触发

keyup 键盘抬起触发

4.文本事件

input 表单输出触发

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        div{
            clear: both;
        }
        input{
            height: 50px;
            width: 400px;
            transition: 2s 0.1s all;
            float: left;
        }
        button{
            height: 50px;
            margin-left: 10px;
            background-color: skyblue;
            float: left;
        }
        .in>input:focus{
            transform: scale(1.02);
        }
        .sp{
            margin-left: 360px;
            height: 10px;
            width: 40px;
            opacity: 0;
        }
    </style>
</head>
<body>
    <div class="in">
        <input type="text" placeholder="请发布一条友善的评论">
        <button>发布</button>
    </div>
    <div class="sp">字数</div>
    <script>
        const tx = document.querySelector("input");
        const sp =document.querySelector(".sp");


        tx.addEventListener('focus',function(){
            sp.style.opacity=1
        })

        tx.addEventListener('blur',function(){
            sp.style.opacity=0;
        })

        tx.addEventListener('input',function(){
            let d = tx.value.length;
            sp.innerHTML=`字数${d}/200`;
        })
    </script>
</body>
</html>

5.事件对象

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

button.addEventListener('click',function(e){
    console.log(e);
})

2.常用属性

1.type

获取当前事件的类型

2.client

获取光标相对于

6.环境对象

每个函数里面都有this 环境对象 普通函数里面this指向的是window

this谁调用,this就是谁

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        .body{
            height: 300px;
            width: 400px;
            background-image: linear-gradient(30deg,yellow,red);
            position: relative;
        }
        .top{
            height: 100px;
            width: 400px;
        }
        .foot{
            height: 200px;
            width: 400px;
            background-color: skyblue;
            position: absolute;
            opacity: 0;
        }
        .leftfloat{
            float: left;
        }
        .clearfloat{
            clear: both;
        }
        a{
            text-decoration: none;
        }
        .activate{
            opacity: 1;
        }
    </style>
</head>
<body>
    <div class="body clearfloat">
        <div class="top">模块
            <a class="item item1" href="#">美术</a>
            <a class="item item2" href="#">音乐</a>
            <a class="item item3" href="#">数学</a>
        </div>
        <div class="bottom">
            <div class="foot">111</div>
            <div class="foot">222</div>
            <div class="foot">333</div>
        </div>
    </div>
    <script>
        const as = document.querySelectorAll("a");
        const it = document.querySelectorAll(".foot");

        for (let i=0;i<as.length;i++)
        {
            as[i].addEventListener('mouseenter',function(){
                /* it[i].className="foot activate"; */
                it[i].classList.add('activate');
            })
            as[i].addEventListener('mouseleave',function(){
                /* it[i].className="foot"; */
                it[i].classList.remove('activate');
            })
        }
    </script>
</body>
</html>

7.页面加载事件

load

给window添加load事件

也可以针对某一资源绑定load事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        window.addEventListener('load',function(){
            const btn = document.querySelector("button");

            btn.addEventListener('click',function(){
                alert("11");
            })
        })
    </script>
</head>
<body>
    <button>点击</button>
</body>
</html>

DOMContentLoaded

  • 给document添加事件DOMContentLoaded
document.addEventListener('DOMContentLoaded',function(){
    const btn = document.querySelector("button");

    btn.addEventListener('click',function(){
        alert("11");
    })
})

8.元素滚动事件

固定导航栏

事件名scroll

window.addEventListener('scroll',function(){
    console.log("滚动");
})

当滚动到某距离时,显示

ScrollLeft和ScrollTop属性 (可读写)

被卷去的长度px

const div = document.querySelector("div");

div.addEventListener('scroll',function(){
    const a = div.scrollTop;
    if (a>=100)
    {
        alert(">=100");
    }
})

ScrollTo()方法

元素.scrollTo(x,y)

让页面滚动到y轴1000像素的地方 window.scrollTo(x,y);

window.scrollTo(0,1000);

9.页面尺寸事件

1.resize

window.addEventListener('resize',function(){
    console.log("1");
})
console.log(div.clientWidth);
console.log(div.clientHeight);

10.元素的尺寸和位置

offsetWidth和offsetHeight(只读)

padding+border+内容

受父亲元素的影响

offsetTop和offsetLeft的基准

带有定位的父级

如果都没有则以文档左上角为准

5.事件流

1.事件流

事件流指的是事件完整执行过程中的流动路径

2.事件捕获

DOM.(事件类型,事件处理函数,是否使用捕获机制)

addEventListener第三个参数传入true代表是捕获阶段触发

若传入false代表冒泡阶段触发,默认就是false

3.事件冒泡

当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中一次被触发,这一事件被称为冒泡

当一个事件触发事件后,会依次向上调用所有父级元素的同名事件

4.阻止冒泡

事件对象.stopPropagation()

阻止冒泡阻断事件的流动传播,不光在冒泡阶段有效,捕获阶段也有效

6.事件解绑

1.L0

<script>
    const btn = document.querySelector("button");
    btn.onclick = function(){
        alert("1");
    }
    btn.onclick=null;
</script>

2.L2

function a(){ 
    alert("1");
};
btn.addEventListener('click',a);
btn.removeEventListener('click',a);

匿名函数无法解绑

mouseover mouseout

鼠标经过 鼠标离开

mouseenter mouseleave

鼠标经过 鼠标离开

7.事件委托

利用事件冒泡的特性

  • 给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件
  • ul.addEventListener(‘click’,function(){})
<script>
    const ul = document.querySelector("ul");
	ul.addEventListener('click',function(){
    alert("hh");
})
</script>

找到tagName判断指定的元素

if (e.target.tagName=="LI")
{
    e.target.style.color="red";
}

8.阻止元素的默认行为

阻止元素的默认行为

e.preventDefault();

9.M端事件

M端-移动端

开始触屏事件

touchstart

离开事件

touchend

移动

touchmove

15.作用域

1.局部作用域

函数作用域和块作用域

1.函数作用域

在函数内部声明的变量只能在函数内部访问,外部无法直接访问

2.块作用域

使用{}包裹的代码称为代码块

const let 会产生块作用域

var不会产生

2.全局作用域

script标签和.js文件

3.作用域链

本质是底层的变量查找机制

  • 在函数执行时,会优先查找当前函数作用域中查找变量
  • 如果查找不到,父级作用域直到全局变量直到全局作用域

子作用域能够访问父作用域,父级作用域无法访问子级作用域

4.垃圾回收机制

引用计数法

引用计数法,查看一个对象是否有指向它的引用,没用引用就回收对象

标记清楚法

回收没有用的对象(即无法访问到的对象)

5.闭包

封装数据,提供操作,外部也可以访问函数内部的变量

function outer(){
    let a=10;
    function fn(){
        console.log(a);
    }
    fn();
}

防止被修改,变量为全局变量容易被修改

6.变量提升

把所有var声明的变量提升到当前作用域的最前面

只提升声明,不提升赋值

只提升到当前作用域的最前面

实际开发中推荐先声明再访问变量

7.函数提升

把所有function声明的函数提升到当前作用域的最前面

只提升声明,不提升函数调用

只提升到当前作用域的最前面

8.函数动态参数

agruments 动态参数只存在于函数里面

是伪数组

剩余参数 类似于Java的…

…展开运算符

let arr=[1,2,3];

16.箭头函数

只有一个形参可以省略小括号

只有一行代码可以写到一行不需要{}并且无需return直接返回值

const fn1 = (x) => {
    console.log(x);
}

const fn = x => {
    return x+1;
}
let a = fn(2);
console.log(a);

const fn2 = (x,y) => x+y;

箭头函数可以直接返回一个对象

const fn3 = (uname) => (
    {"classname":uname}
)
const class1 = fn3("1111");   
console.log(class1);

箭头函数的this是上一层作用域的this指向

forEach()方法用于调用数组的每个元素,并且将元素传递给回调函数

const arr = ['p','c','v','b','n'];
const result = arr.forEach(function(item,index){
    console.log(item);
    console.log(index);
})

17.解构赋值

1.数组解构

将数组的单元值快速批量赋值给一系列变量的简洁语法

基本语法:

​ 赋值运算符 = 左侧的[]用于批量声明变量,右侧数组的单元值将赋值给左侧的变量

变量的顺序对应数组单元值的位置依次进行赋值操作

const [max,min,qvg] = [100,60,80]

1.变量多,单元值少的情况

多的变量为undefined

2.变量少,单元值多

用剩余参数接受

3.防止undefined传递

设置默认参数(a=1,b=1)

[a=1,b=1]

4.按需导入赋值

const [a,,b,c,d] = [1,2,3,4]

5.支持多维数组的解构

2.对象解构

属性名和变量名必须一致才行

对象解构的变量名可以重新改名

旧值:新值

const {uname:name,age}={uname:"1",age:100}

数组对象的解构

const pg =[
    {
        name:"pg",
        age:199
    }
]
const [{name,age}] =pg;

console.log(name);
console.log(age);

多级对象的解构

const ap = {
    name:"1",
    app:{
        name1:"2",
        name2:"3"
    }
}

const {name,app:{name1,name2}}=ap;
console.log(name);
console.log(name1);
console.log(name2);

18.深入对象

了解面向对象的基础概念,能够利用构造函数创建对象。

构造函数

构造函数是专门用于创建对象的函数,如果一个函数使用 new 关键字调用,那么这个函数就是构造函数。

<script>
  // 定义函数
  function foo() {
    console.log('通过 new 也能调用函数...');
  }
  // 调用函数
  new foo;
</script>

总结:

  1. 使用 new 关键字调用函数的行为被称为实例化
  2. 实例化构造函数时没有参数时可以省略 ()
  3. 构造函数的返回值即为新创建的对象
  4. 构造函数内部的 return 返回的值无效!

注:实践中为了从视觉上区分构造函数和普通函数,习惯将构造函数的首字母大写。

实例成员

通过构造函数创建的对象称为实例对象,实例对象中的属性和方法称为实例成员。

<script>
  // 构造函数
  function Person() {
    // 构造函数内部的 this 就是实例对象
    // 实例对象中动态添加属性
    this.name = '小明'
    // 实例对象动态添加方法
    this.sayHi = function () {
      console.log('大家好~')
    }
  }
  // 实例化,p1 是实例对象
  // p1 实际就是 构造函数内部的 this
  const p1 = new Person()
  console.log(p1)
  console.log(p1.name) // 访问实例属性
  p1.sayHi() // 调用实例方法
</script>

总结:

  1. 构造函数内部 this 实际上就是实例对象,为其动态添加的属性和方法即为实例成员
  2. 为构造函数传入参数,动态创建结构相同但值不同的对象

注:构造函数创建的实例对象彼此独立互不影响。

静态成员

在 JavaScript 中底层函数本质上也是对象类型,因此允许直接为函数动态添加属性或方法,构造函数的属性和方法被称为静态成员。

<script>
  // 构造函数
  function Person(name, age) {
    // 省略实例成员
  }
  // 静态属性
  Person.eyes = 2
  Person.arms = 2
  // 静态方法
  Person.walk = function () {
    console.log('^_^人都会走路...')
    // this 指向 Person
    console.log(this.eyes)
  }
</script>

总结:

  1. 静态成员指的是添加到构造函数本身的属性和方法
  2. 一般公共特征的属性或方法静态成员设置为静态成员
  3. 静态成员方法中的 this 指向构造函数本身

19.内置构造函数

掌握各引用类型和包装类型对象属性和方法的使用。

在 JavaScript 中最主要的数据类型有 6 种,分别是字符串、数值、布尔、undefined、null 和 对象,常见的对象类型数据包括数组和普通对象。其中字符串、数值、布尔、undefined、null 也被称为简单类型或基础类型,对象也被称为引用类型。

在 JavaScript 内置了一些构造函数,绝大部的数据处理都是基于这些构造函数实现的,JavaScript 基础阶段学习的 Date 就是内置的构造函数。

<script>
  // 实例化
	let date = new Date();
  
  // date 即为实例对象
  console.log(date);
</script>

甚至字符串、数值、布尔、数组、普通对象也都有专门的构造函数,用于创建对应类型的数据。

Object

Object 是内置的构造函数,用于创建普通对象。

<script>
  // 通过构造函数创建普通对象
  const user = new Object({name: '小明', age: 15})

  // 这种方式声明的变量称为【字面量】
  let student = {name: '杜子腾', age: 21}
  
  // 对象语法简写
  let name = '小红';
  let people = {
    // 相当于 name: name
    name,
    // 相当于 walk: function () {}
    walk () {
      console.log('人都要走路...');
    }
  }

  console.log(student.constructor);
  console.log(user.constructor);
  console.log(student instanceof Object);
</script>

总结:

  1. 推荐使用字面量方式声明对象,而不是 Object 构造函数
  2. Object.assign 静态方法创建新的对象
  3. Object.keys 静态方法获取对象中所有属性
  4. Object.values 表态方法获取对象中所有属性值

Array

Array 是内置的构造函数,用于创建数组。

<script>
  // 构造函数创建数组
  let arr = new Array(5, 7, 8);

  // 字面量方式创建数组
  let list = ['html', 'css', 'javascript']

</script>

数组赋值后,无论修改哪个变量另一个对象的数据值也会相当发生改变。

总结:

  1. 推荐使用字面量方式声明数组,而不是 Array 构造函数

  2. 实例方法 forEach 用于遍历数组,替代 for 循环 (重点)

  3. 实例方法 filter 过滤数组单元值,生成新数组(重点)

  4. 实例方法 map 迭代原数组,生成新数组(重点)

  5. 实例方法 join 数组元素拼接为字符串,返回字符串(重点)

  6. 实例方法 find 查找元素, 返回符合测试条件的第一个数组元素值,如果没有符合条件的则返回 undefined(重点)

  7. 实例方法every 检测数组所有元素是否都符合指定条件,如果所有元素都通过检测返回 true,否则返回 false(重点)

  8. 实例方法some 检测数组中的元素是否满足指定条件 如果数组中有元素满足条件返回 true,否则返回 false

  9. 实例方法 concat 合并两个数组,返回生成新数组

  10. 实例方法 sort 对原数组单元值排序

  11. 实例方法 splice 删除或替换原数组单元

  12. 实例方法 reverse 反转数组

  13. 实例方法 findIndex 查找元素的索引值

包装类型

在 JavaScript 中的字符串、数值、布尔具有对象的使用特征,如具有属性和方法,如下代码举例:

<script>
  // 字符串类型
  const str = 'hello world!'
 	// 统计字符的长度(字符数量)
  console.log(str.length)
  
  // 数值类型
  const price = 12.345
  // 保留两位小数
  price.toFixed(2) // 12.34
</script>

之所以具有对象特征的原因是字符串、数值、布尔类型数据是 JavaScript 底层使用 Object 构造函数“包装”来的,被称为包装类型。

String

String 是内置的构造函数,用于创建字符串。

<script>
  // 使用构造函数创建字符串
  let str = new String('hello world!');

  // 字面量创建字符串
  let str2 = '你好,世界!';

  // 检测是否属于同一个构造函数
  console.log(str.constructor === str2.constructor); // true
  console.log(str instanceof String); // false
</script>

总结:

  1. 实例属性 length 用来获取字符串的度长(重点)
  2. 实例方法 split('分隔符') 用来将字符串拆分成数组(重点)
  3. 实例方法 substring(需要截取的第一个字符的索引[,结束的索引号]) 用于字符串截取(重点)
  4. 实例方法 startsWith(检测字符串[, 检测位置索引号]) 检测是否以某字符开头(重点)
  5. 实例方法 includes(搜索的字符串[, 检测位置索引号]) 判断一个字符串是否包含在另一个字符串中,根据情况返回 true 或 false(重点)
  6. 实例方法 toUpperCase 用于将字母转换成大写
  7. 实例方法 toLowerCase 用于将就转换成小写
  8. 实例方法 indexOf 检测是否包含某字符
  9. 实例方法 endsWith 检测是否以某字符结尾
  10. 实例方法 replace 用于替换字符串,支持正则匹配
  11. 实例方法 match 用于查找字符串,支持正则匹配

注:String 也可以当做普通函数使用,这时它的作用是强制转换成字符串数据类型。

Number

Number 是内置的构造函数,用于创建数值。

<script>
  // 使用构造函数创建数值
  let x = new Number('10')
  let y = new Number(5)

  // 字面量创建数值
  let z = 20

</script>

总结:

  1. 推荐使用字面量方式声明数值,而不是 Number 构造函数
  2. 实例方法 toFixed 用于设置保留小数位的长度

20.构造函数

对比以下通过面向对象的构造函数实现的封装:

<script>
  function Person() {
    this.name = '佚名'
    // 设置名字
    this.setName = function (name) {
      this.name = name
    }
    // 读取名字
    this.getName = () => {
      console.log(this.name)
    }
  }

  // 实例对像,获得了构造函数中封装的所有逻辑
  let p1 = new Person()
  p1.setName('小明')
  console.log(p1.name)

  // 实例对象
  let p2 = new Person()
  console.log(p2.name)
</script>

封装是面向对象思想中比较重要的一部分,js面向对象可以通过构造函数实现的封装。

同样的将变量和函数组合到了一起并能通过 this 实现数据的共享,所不同的是借助构造函数创建出来的实例对象之

间是彼此不影响的

总结:

  1. 构造函数体现了面向对象的封装特性
  2. 构造函数实例创建的对象彼此独立、互不影响

封装是面向对象思想中比较重要的一部分,js面向对象可以通过构造函数实现的封装。

前面我们学过的构造函数方法很好用,但是 存在浪费内存的问题

21.原型对象

构造函数通过原型分配的函数是所有对象所 共享的。

  • JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象,所以我们也称为原型对象
  • 这个对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存
  • 我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。
  • 构造函数和原型对象中的this 都指向 实例化的对象
<script>
  function Person() {
    
  }

  // 每个函数都有 prototype 属性
  console.log(Person.prototype)
</script>

了解了 JavaScript 中构造函数与原型对象的关系后,再来看原型对象具体的作用,如下代码所示:

<script>
  function Person() {
    // 此处未定义任何方法
  }

  // 为构造函数的原型对象添加方法
  Person.prototype.sayHi = function () {
    console.log('Hi~');
  }
	
  // 实例化
  let p1 = new Person();
  p1.sayHi(); // 输出结果为 Hi~
</script>

构造函数 Person 中未定义任何方法,这时实例对象调用了原型对象中的方法 sayHi,接下来改动一下代码:

<script>
  function Person() {
    // 此处定义同名方法 sayHi
    this.sayHi = function () {
      console.log('嗨!');
    }
  }

  // 为构造函数的原型对象添加方法
  Person.prototype.sayHi = function () {
    console.log('Hi~');
  }

  let p1 = new Person();
  p1.sayHi(); // 输出结果为 嗨!
</script>

构造函数 Person 中定义与原型对象中相同名称的方法,这时实例对象调用则是构造函中的方法 sayHi

通过以上两个简单示例不难发现 JavaScript 中对象的工作机制:当访问对象的属性或方法时,先在当前实例对象是查找,然后再去原型对象查找,并且原型对象被所有实例共享。

<script>
	function Person() {
    // 此处定义同名方法 sayHi
    this.sayHi = function () {
      console.log('嗨!' + this.name)
    }
  }

  // 为构造函数的原型对象添加方法
  Person.prototype.sayHi = function () {
    console.log('Hi~' + this.name)
  }
  // 在构造函数的原型对象上添加属性
  Person.prototype.name = '小明'

  let p1 = new Person()
  p1.sayHi(); // 输出结果为 嗨!
  
  let p2 = new Person()
  p2.sayHi()
</script>

总结:结合构造函数原型的特征,实际开发重往往会将封装的功能函数添加到原型对象中。

1.constructor 属性

在哪里? 每个原型对象里面都有个constructor 属性(constructor 构造函数)

作用:该属性指向该原型对象的构造函数, 简单理解,就是指向我的爸爸,我是有爸爸的孩子

使用场景:

如果有多个对象的方法,我们可以给原型对象采取对象形式赋值.

但是这样就会覆盖构造函数原型对象原来的内容,这样修改后的原型对象 constructor 就不再指向当前构造函数了

此时,我们可以在修改后的原型对象中,添加一个 constructor 指向原来的构造函数。

2.对象原型

对象都会有一个属性 proto 指向构造函数的 prototype 原型对象,之所以我们对象可以使用构造函数 prototype

原型对象的属性和方法,就是因为对象有 proto 原型的存在。

注意:

  • proto 是JS非标准属性
  • [[prototype]]和__proto__意义相同
  • 用来表明当前实例对象指向哪个原型对象prototype
  • __proto__对象原型里面也有一个 constructor属性,指向创建该实例对象的构造函数

3.原型继承

继承是面向对象编程的另一个特征,通过继承进一步提升代码封装的程度,JavaScript 中大多是借助原型对象实现继承

的特性

<body>
  <script>
    // 继续抽取   公共的部分放到原型上
    // const Person1 = {
    //   eyes: 2,
    //   head: 1
    // }
    // const Person2 = {
    //   eyes: 2,
    //   head: 1
    // }
    // 构造函数  new 出来的对象 结构一样,但是对象不一样
    function Person() {
      this.eyes = 2
      this.head = 1
    }
    // console.log(new Person)
    // 女人  构造函数   继承  想要 继承 Person
    function Woman() {

    }
    // Woman 通过原型来继承 Person
    // 父构造函数(父类)   子构造函数(子类)
    // 子类的原型 =  new 父类  
    Woman.prototype = new Person()   // {eyes: 2, head: 1} 
    // 指回原来的构造函数
    Woman.prototype.constructor = Woman

    // 给女人添加一个方法  生孩子
    Woman.prototype.baby = function () {
      console.log('宝贝')
    }
    const red = new Woman()
    console.log(red)
    // console.log(Woman.prototype)
    // 男人 构造函数  继承  想要 继承 Person
    function Man() {

    }
    // 通过 原型继承 Person
    Man.prototype = new Person()
    Man.prototype.constructor = Man
    const pink = new Man()
    console.log(pink)
  </script>
</body>

4.原型链

基于原型对象的继承使得不同构造函数的原型对象关联在一起,并且这种关联的关系是一种链状的结构,我们将原型对

象的链状结构关系称为原型链

<body>
  <script>
    // function Objetc() {}
    console.log(Object.prototype)
    console.log(Object.prototype.__proto__)

    function Person() {

    }
    const ldh = new Person()
    // console.log(ldh.__proto__ === Person.prototype)
    // console.log(Person.prototype.__proto__ === Object.prototype)
    console.log(ldh instanceof Person)
    console.log(ldh instanceof Object)
    console.log(ldh instanceof Array)
    console.log([1, 2, 3] instanceof Array)
    console.log(Array instanceof Object)
  </script>
</body>

① 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。

② 如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)

③ 如果还没有就查找原型对象的原型(Object的原型对象)

④ 依此类推一直找到 Object 为止(null)

⑤ __proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线

⑥ 可以使用 instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

5.案例

<script>
    function Modal(title='',message=''){
    this.ModalBox = document.createElement('div');
    this.ModalBox.className="modal";
    this.ModalBox.innerHTML=`
            <div id="header">${title}</div>
            <div id="bottom">${message}</div>
            `
}

Modal.prototype.open=function(){
    const box = document.querySelector(".modal");
    box && box.remove();
    document.body.append(this.ModalBox);
}
Modal.prototype.close=function(){
    this.ModalBox.remove();
}
document.querySelector("#delete").addEventListener("click",()=>{
    const col = new Modal("警告","确认删除");
    col.open();

    document.querySelector("#header").addEventListener("click",()=>{
        col.close();
    })
})
document.querySelector("#login").addEventListener("click",()=>{
    const del = new Modal("提示","未登录");
    del.open();

    document.querySelector("#header").addEventListener("click",()=>{
        del.close();
    })
})
</script>

22.深浅拷贝

1.浅拷贝

首先浅拷贝和深拷贝只针对引用类型

浅拷贝:拷贝的是地址

常见方法:

  1. 拷贝对象:Object.assgin() / 展开运算符 {…obj} 拷贝对象
  2. 拷贝数组:Array.prototype.concat() 或者 […arr]

如果是简单数据类型拷贝值,引用数据类型拷贝的是地址 (简单理解: 如果是单层对象,没问题,如果有多层就有问题)

2.深拷贝

首先浅拷贝和深拷贝只针对引用类型

深拷贝:拷贝的是对象,不是地址

常见方法:

  1. 通过递归实现深拷贝
  2. lodash/cloneDeep
  3. 通过JSON.stringify()实现

递归实现深拷贝

函数递归:

如果一个函数在内部可以调用其本身,那么这个函数就是递归函数

  • 简单理解:函数内部自己调用自己, 这个函数就是递归函数
  • 递归函数的作用和循环效果类似
  • 由于递归很容易发生“栈溢出”错误(stack overflow),所以必须要加退出条件 return
<body>
  <script>
    const obj = {
      uname: 'pink',
      age: 18,
      hobby: ['乒乓球', '足球'],
      family: {
        baby: '小pink'
      }
    }
    const o = {}
    // 拷贝函数
    function deepCopy(newObj, oldObj) {
      debugger
      for (let k in oldObj) {
        // 处理数组的问题  一定先写数组 在写 对象 不能颠倒
        if (oldObj[k] instanceof Array) {
          newObj[k] = []
          //  newObj[k] 接收 []  hobby
          //  oldObj[k]   ['乒乓球', '足球']
          deepCopy(newObj[k], oldObj[k])
        } else if (oldObj[k] instanceof Object) {
          newObj[k] = {}
          deepCopy(newObj[k], oldObj[k])
        }
        else {
          //  k  属性名 uname age    oldObj[k]  属性值  18
          // newObj[k]  === o.uname  给新对象添加属性
          newObj[k] = oldObj[k]
        }
      }
    }
    deepCopy(o, obj) // 函数调用  两个参数 o 新对象  obj 旧对象
    console.log(o)
    o.age = 20
    o.hobby[0] = '篮球'
    o.family.baby = '老pink'
    console.log(obj)
    console.log([1, 23] instanceof Object)
    // 复习
    // const obj = {
    //   uname: 'pink',
    //   age: 18,
    //   hobby: ['乒乓球', '足球']
    // }
    // function deepCopy({ }, oldObj) {
    //   // k 属性名  oldObj[k] 属性值
    //   for (let k in oldObj) {
    //     // 处理数组的问题   k 变量
    //     newObj[k] = oldObj[k]
    //     // o.uname = 'pink'
    //     // newObj.k  = 'pink'
    //   }
    // }
  </script>
</body>

js库lodash里面cloneDeep内部实现了深拷贝

<body>
  <!-- 先引用 -->
  <script src="./lodash.min.js"></script>
  <script>
    const obj = {
      uname: 'pink',
      age: 18,
      hobby: ['乒乓球', '足球'],
      family: {
        baby: '小pink'
      }
    }
    const o = _.cloneDeep(obj)
    console.log(o)
    o.family.baby = '老pink'
    console.log(obj)
  </script>
</body>

JSON序列化

<body>
  <script>
    const obj = {
      uname: 'pink',
      age: 18,
      hobby: ['乒乓球', '足球'],
      family: {
        baby: '小pink'
      }
    }
    // 把对象转换为 JSON 字符串
    // console.log(JSON.stringify(obj))
    const o = JSON.parse(JSON.stringify(obj))
    console.log(o)
    o.family.baby = '123'
    console.log(obj)
  </script>
</body>

23.异常处理

了解 JavaScript 中程序异常处理的方法,提升代码运行的健壮性。

1.throw

异常处理是指预估代码执行过程中可能发生的错误,然后最大程度的避免错误的发生导致整个程序无法继续运行

总结:

  1. throw 抛出异常信息,程序也会终止执行
  2. throw 后面跟的是错误提示信息
  3. Error 对象配合 throw 使用,能够设置更详细的错误信息
<script>
  function counter(x, y) {

    if(!x || !y) {
      // throw '参数不能为空!';
      throw new Error('参数不能为空!')
    }

    return x + y
  }

  counter()
</script>

总结:

  1. throw 抛出异常信息,程序也会终止执行
  2. throw 后面跟的是错误提示信息
  3. Error 对象配合 throw 使用,能够设置更详细的错误信息

2.try … catch

<script>
   function foo() {
      try {
        // 查找 DOM 节点
        const p = document.querySelector('.p')
        p.style.color = 'red'
      } catch (error) {
        // try 代码段中执行有错误时,会执行 catch 代码段
        // 查看错误信息
        console.log(error.message)
        // 终止代码继续执行
        return

      }
      finally {
          alert('执行')
      }
      console.log('如果出现错误,我的语句不会执行')
    }
    foo()
</script>

总结:

  1. try...catch 用于捕获错误信息
  2. 将预估可能发生错误的代码写在 try 代码段中
  3. 如果 try 代码段中出现错误后,会执行 catch 代码段,并截获到错误信息

3.debugger

相当于断点调试

24.处理this

了解函数中 this 在不同场景下的默认值,知道动态指定函数 this 值的方法。

this 是 JavaScript 最具“魅惑”的知识点,不同的应用场合 this 的取值可能会有意想不到的结果,在此我们对以往学习过的关于【 this 默认的取值】情况进行归纳和总结。

1.普通函数

普通函数的调用方式决定了 this 的值,即【谁调用 this 的值指向谁】,如下代码所示:

<script>
  // 普通函数
  function sayHi() {
    console.log(this)  
  }
  // 函数表达式
  const sayHello = function () {
    console.log(this)
  }
  // 函数的调用方式决定了 this 的值
  sayHi() // window
  window.sayHi()
	

// 普通对象
  const user = {
    name: '小明',
    walk: function () {
      console.log(this)
    }
  }
  // 动态为 user 添加方法
  user.sayHi = sayHi
  uesr.sayHello = sayHello
  // 函数调用方式,决定了 this 的值
  user.sayHi()
  user.sayHello()
</script>

注: 普通函数没有明确调用者时 this 值为 window,严格模式下没有调用者时 this 的值为 undefined

2.箭头函数

箭头函数中的 this 与普通函数完全不同,也不受调用方式的影响,事实上箭头函数中并不存在 this !箭头函数中访问的 this 不过是箭头函数所在作用域的 this 变量。

<script>
    
  console.log(this) // 此处为 window
  // 箭头函数
  const sayHi = function() {
    console.log(this) // 该箭头函数中的 this 为函数声明环境中 this 一致
  }
  // 普通对象
  const user = {
    name: '小明',
    // 该箭头函数中的 this 为函数声明环境中 this 一致
    walk: () => {
      console.log(this)
    },
    
    sleep: function () {
      let str = 'hello'
      console.log(this)
      let fn = () => {
        console.log(str)
        console.log(this) // 该箭头函数中的 this 与 sleep 中的 this 一致
      }
      // 调用箭头函数
      fn();
    }
  }

  // 动态添加方法
  user.sayHi = sayHi
  
  // 函数调用
  user.sayHi()
  user.sleep()
  user.walk()
</script>

在开发中【使用箭头函数前需要考虑函数中 this 的值】,事件回调函数使用箭头函数时,this 为全局的 window,因此DOM事件回调函数不推荐使用箭头函数,如下代码所示:

<script>
  // DOM 节点
  const btn = document.querySelector('.btn')
  // 箭头函数 此时 this 指向了 window
  btn.addEventListener('click', () => {
    console.log(this)
  })
  // 普通函数 此时 this 指向了 DOM 对象
  btn.addEventListener('click', function () {
    console.log(this)
  })
</script>

同样由于箭头函数 this 的原因,基于原型的面向对象也不推荐采用箭头函数,如下代码所示:

<script>
  function Person() {
  }
  // 原型对像上添加了箭头函数
  Person.prototype.walk = () => {
    console.log('人都要走路...')
    console.log(this); // window
  }
  const p1 = new Person()
  p1.walk()
</script>

3.改变this指向

以上归纳了普通函数和箭头函数中关于 this 默认值的情形,不仅如此 JavaScript 中还允许指定函数中 this 的指向,有 3 个方法可以动态指定普通函数中 this 的指向:

call

使用 call 方法调用函数,同时指定函数中 this 的值,使用方法如下代码所示:

<script>
  // 普通函数
  function sayHi() {
    console.log(this);
  }

  let user = {
    name: '小明',
    age: 18
  }

  let student = {
    name: '小红',
    age: 16
  }

  // 调用函数并指定 this 的值
  sayHi.call(user); // this 值为 user
  sayHi.call(student); // this 值为 student

  // 求和函数
  function counter(x, y) {
    return x + y;
  }

  // 调用 counter 函数,并传入参数
  let result = counter.call(null, 5, 10);
  console.log(result);
</script>

总结:

  1. call 方法能够在调用函数的同时指定 this 的值
  2. 使用 call 方法调用函数时,第1个参数为 this 指定的值
  3. call 方法的其余参数会依次自动传入函数做为函数的参数

apply

使用 call 方法调用函数,同时指定函数中 this 的值,使用方法如下代码所示:

<script>
  // 普通函数
  function sayHi() {
    console.log(this)
  }

  let user = {
    name: '小明',
    age: 18
  }

  let student = {
    name: '小红',
    age: 16
  }

  // 调用函数并指定 this 的值
  sayHi.apply(user) // this 值为 user
  sayHi.apply(student) // this 值为 student

  // 求和函数
  function counter(x, y) {
    return x + y
  }
  // 调用 counter 函数,并传入参数
  let result = counter.apply(null, [5, 10])
  console.log(result)
</script>

总结:

  1. apply 方法能够在调用函数的同时指定 this 的值
  2. 使用 apply 方法调用函数时,第1个参数为 this 指定的值
  3. apply 方法第2个参数为数组,数组的单元值依次自动传入函数做为函数的参数

bind

bind 方法并不会调用函数,而是创建一个指定了 this 值的新函数,使用方法如下代码所示:

<script>
  // 普通函数
  function sayHi() {
    console.log(this)
  }
  let user = {
    name: '小明',
    age: 18
  }
  // 调用 bind 指定 this 的值
  let sayHello = sayHi.bind(user);
  // 调用使用 bind 创建的新函数
  sayHello()
</script>

注:bind 方法创建新的函数,与原函数的唯一的变化是改变了 this 的值。

25.防抖节流

  1. 防抖(debounce)
    所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间
//防抖的函数
function debounce(func,wait,immediate){
    let timeout;
	return function(){
        //这里利用了闭包
        clearTimeout(timeout);
   
        if(immediate){
             //立即执行
            let callNow = !timeout;
            //如果是第一次点的话,timeout是没有值的
            
            timeout = setTimeout(function(){
                timeout = null;
            	},wait);
            
            if(callNow){      
                func();    
                }
        }
        else{
            //不会立即执行
            timeout = setTimeout(func(),wait);
        }	
	}
}

let count = 0;
	
	let container = document.querySelector("#container");

	//为了展示事件是如何频繁发生
	function doSomeThing (){     
        container.innerHTML = count ++;
    }

	container.onmousemove = debounce(doSomeThing,300,true);
//注意这时候debounce的agruments装的是事件对象mousemove
//这个true是为了一开始立即执行
  1. 节流(throttle)
    所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数

1.时间戳实现方式

function throttle(func,wait){

	//之前的时间戳
	let old = 0;
	return function(){
	//获取当前的时间戳
	let now = new Date().valueOf();
	if(now - old > wait){
		//立即执行
		func();
		
		old = now;	
		}
	}
}

2.定时器

function throttle(func,wait){
    let timeout;
    return function(){
        if(!timeout){
            timeout = setTimeout(function(){
                func();
                timeout = null;
            },wait);
        }    
    }
}

26.ES6-ES11

let genericSymbol = Symbol();

let fooGlobalSymbol = Symbol.for(“foo”);

console.log(BarSymbol.hasInstance);

1.迭代器

arr=["1","2","3","4"];

let iterator = arr[Symbol.iterator]();

console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

2.自定义遍历数据

const class1 ={
    name:"name",
    arr:["1","2","3","4"],
    [Symbol.iterator](){
        let index=0;
        let _this = this;
        return {
            next(){
                if (index < _this.arr.length){
                    const result = {value:_this.arr[index],done: false};
                    index++;
                    return result;
                }else{
                    return {value:undefined,done: true};
                }
                
            }
        };
    }
}


for (let v of class1) {
    console.log(v);
}

3.生成器函数

function * gener(){
    console.log("gen");
}

let iterator = gener();

iterator.next();

只有调用了next函数才会执行

function * gener(){
    yield console.log(1);

    yield console.log(2);

    yield console.log(3);
}

let iterator = gener();

iterator.next();
iterator.next();
iterator.next();

yield分隔符

生成器的函数参数

function * gener(arg){
    console.log(arg)
    yield console.log(1);;

    yield console.log(2);

    yield console.log(3);
}

let iterator = gener('AAA');

生成器函数案例1

function one() { setTimeout(() => { console.log(1), iterator.next() }, 1000) };
function two() {
    setTimeout(() => {
        console.log(2),
            iterator.next()
    }, 2000)
};
function three() {
    setTimeout(() => {
        console.log(3)
    }, 3000)
};

function * set(){
    yield one();

    yield two();

    yield three();
}

let iterator = set();

iterator.next();

生成器函数案例2

function getuser(){
    setTimeout(()=>{
        let data ="user"
        iterator.next(data);
    },1000)
}

function getdata(){
    setTimeout(()=>{
        let data ="data";
        iterator.next(data);
    },1000)
}

function getgood(){
    setTimeout(()=>{
        let data ="good";
        iterator.next(data);
    },1000)
}

function * get(){
    let user = yield getuser();
    console.log(user);
    let data = yield getdata();
    console.log(data);
    let good = yield getgood();
    console.log(good);
}

let iterator = get();

iterator.next();

3.集合Set

const set = new Set([1,2,3,4,5,6]);
/* 添加 */
set.add(7);
/* 判断是否含有 */
console.log(set.has(5));

/* 遍历 */
for (const iterator of set) {
    console.log(iterator);
}
console.log("————————————————————");
/* 删除 */
set.delete(7)

for (const iterator of set) {
    console.log(iterator);
}

/* 清空 */
set.clear();

for (const iterator of set) {
    console.log(iterator);
}

console.log("————————————————————");

案例

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

/* 去重 */
let narr = [...(new Set(arr))];
console.log(narr);
console.log("————————————————————");
/* 求交集 */
let nay = [6,4,3];
let nay1 = new Set(nay);
let narr1 = new Set(narr);
for (const i of narr1) {
    if (!nay1.has(i)){
        narr1.delete(i);
    }
}

for (const i of narr1) {
    console.log(i);
}
console.log("————————————————————");
/* 求差集 */
let nay2 = new Set(nay);
let narr2 = new Set(narr);
for (const i of narr2) {
    if (nay2.has(i)){
        narr2.delete(i);
    }
}

for (const i of narr2) {
    console.log(i);
}
console.log("————————————————————");
/* 求并集 */
let nay3 = new Set(nay);
let narr3 = new Set(narr);
for (const i of nay3) {
    narr3.add(i);
}
let narr4 = [...(new Set(narr3))];
console.log(narr4);

4.Map

键值对

const map = new Map();

/* 添加元素 */
map.set("stu","zs");

let key = {
    school:"gt"
}

let value = ["1","2"];

map.set(key,value);

for (const iterator of map) {
    console.log(iterator);
}
console.log(map.size);
map.delete("stu");
for (const iterator of map) {
    console.log(iterator);
}

5.class

constructor构造函数

class student{
    constructor(name,age){
        this.name=name;
        this.age=age;
    }

    study(){
        console.log("study");
    }
}

const s = new student("zs",18);
console.log(s);

6.ES10

Object.is 判断两个值是否完全相等

Object.assign 对象的合并

Object.setPrototypeof

Object.getPrototypeof

Object.fromEntries

将二维数组转换为对象

Object.entries

将对象转为二维数组

const result = Object.fromEntries([
    ['name','zs'],
    ['age',[1,2,3,4,5]]
])

console.log(result);

const cl = Object.entries({
    name:"zs"
})

console.log(cl);

数组扩展方法

将多维数组降维

const arr = [1,2,3,[4,5,[6,7,8]]];
//传递的参数为深度
console.log(arr.flat(2));
const arr1 = [1,2,3,4];
const result = arr1.map((item)=>
    [item*10]
);

const result2 = arr1.flatMap((item)=>
    [item*10]
);

console.log(result);
console.log(result2);

flatMap相当于同时执行map 和 flat

7.ES11

私有属性

class person{
    /* 公有属性 */
    name;
    /* 私有属性 */
    #age;
    #weight;

    constructor(name,age,weight){
        this.name=name;
        this.#age=age;
        this.#weight=weight
    }
}

const man = new person("ld",24,180);
console.log(man);

可选链操作符

function main(man){
    const tem = man?.dp?.name;
    console.log(tem);
}

main({
    dp:{
        name:'zs',
        password:'1234'
    },
    ps:{
        host:'127',
        ad:'root'
    }
})

动态import

import(模块).then(module=>{
    module.方法();
});

BigInt类型

let i = 54444n;

console.log(i,typeof i);

/* number->bigint */
let n =99;
let i1 = BigInt(n);
console.log(i1);

/* 最大安全整数 */
let max = Number.MAX_SAFE_INTEGER;
console.log(max);

console.log(BigInt(max)+BigInt(1));
console.log(BigInt(max)+BigInt(2));

globalthis

全局this

console.log(globalThis);