JavaScript

运行在客户端的脚本语言,一种基于对象的编程语言(object-baseb)

组成:

  1. ECMAScript

  2. Web APIs

基础语法(ECMAScript)

  1. 在html文件中的script标签中书写

  2. 常用的输出语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <script>
    //弹出框
    alert('hello world')
    //控制台输出
    console.log('hello world');
    //获取用户输出
    prompt('hello world')

    </script>

常用数据类型

  1. 基本数据类型

    • 字符串:String
    • 数字:number
    • 布尔:boolean
    • 未定义:undefined
    • 空:Null
  2. 复杂数据类型

    • 多种数据类型的容器:Object
    • 数组:Array
    • Function:函数
    • RegEXP:正则表达式
    • Date:日期
  3. 利用typeof检测数据类型

常见的就不多说了,讲一下比较特殊的几个,这也是因为JavaScript是一一种弱类型的语言导致的,对类型的检查并不严格

  • undefined 用type检测为它本身,但null类型检测则为Object

  • 检测number类型时遇到科学技术法的类型会自动解析,如3e2 就是300,也会解析为number类型

  • 检测NaN时,会返回number

  • 检测null为Object

  • 数组使用typeof检测也为object,不一定正确,主要就是JavaScript是一种弱类型的语言导致的

  • 变量提升检测

    1
    2
    3
    console.log(a);//undefined
    console.log(typeof a);//undefined
    var a = 10
  1. 利用字符串拼接

    • +,两边都是字符串时就会做拼接操作,有一方为数字也会拼接为字符串,但当字符串前面有+时就会转换为number类型,通常用这种方法来转换用户通过prompt输入的值,通过这个函数获得的值为字符串类型,前面有+则为number类型,会进行隐式提升

字符串

常用函数
函数名 功能
charAt() 得到指定位置字符串,索引越界会得到空字符串
subString() 截取字符串,前闭后开,参数不接受负数,如果传递的参数前面的比后面大会自动交换两个的位置
substr() 也是截取字符串,接受负数
slice() 提取字符串,参数可以是负数,但参数不会交换位置
toUpperCase() 全部转换为大写
toLowerCase() 转换为小写
indexOf() 检索字符串,返回指定字符串值在字符串中首次出现的位置,匹配不到返回-1

数据类型的转换

  1. Number函数
    • 空字符串转换为0
    • 不是纯数字的字符串转换为NaN
    • 可以识别科学计数法
    • null也为0
    • undefined 为NaN
    • 布尔类型 true为1,false为0
  2. parselnt函数,将字符串转换为整数
    • 传递的是浮点数会自动截取第一位数
    • 不会四舍五入
    • 不以数字开头转为NaN
    • 以数字开头后面的文字会被截取掉
  3. parseFloat函数
    • 不四舍五入
    • 可以将小数字符串转换为小数
    • 自动截取掉第一个非数字字符
  4. String函数
    • 科学计数法和非十进制数字会转换为十进制的值
  5. toString
    • 几乎所有值都有toString方法,功能就是将值转换为字符串
  6. Boolean函数
    • NaN,0,undefined为false

隐式类型的转换

  • 本质就是内部调用Number函数

    • 参与运算的操作数不是数字型,会自动将此操作转换为数字

      3*'5' //15

    • true+tyue = 2

    • false+2 =2

    • 3* ‘2d’ = NaN

    • 小数运算不精准,采用指定小数位数解决

      1
      console.log(Number(0.1+0.2).toFixed(2));

数学函数Math

  • 幂运算和开根号

    1
    2
    Math.pow(2,3)//8
    Math.sqrt(4)//2
  • 取最大,最小值

    1
    2
    Math.max(1,2,3,4,5,6,7,8,9,10)//10
    Math.min(1,2,3,4,5,6,7,8,9,10)//1
  • 向下向上取整

    1
    2
    Math.ceil(1.1)//2
    Math.floor(1.9)//1
  • 随机数

    1
    2
    3
    Math.random()//0-1之间的随机数
    parseInt(Math.random()*(b-a+1))+a//[a,b]之间的随机数

判断是否相等

  • 相等和全等

    == 表示的是不比较类型之后的结果,会进行隐式转换后比较值是否相等,也就是1和‘1’相等、

    === 不仅比较值,也比较类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    1 == true //true
    1 === true //false

    0 == false //true
    0 === false //false

    0 == undefined //false
    0 === undefinde //false

    undefined == null //true
    undefined === null //false

    //NaN 不自等
    NaN == NaN //false
    NaN === NaN //false

小知识点,逻辑运算的优先级为 非 -> 与 -> 或

函数的定义和调用

  • 分为有名称的函数和匿名函数,用function 定义函数
  • 形参和实参个数可以不一样 会自动填上undefind

函数声明的提升

  • 函数声明能被提升,也就是函数定义在下方但在函数声明上方能调用函数

    1
    2
    3
    4
    5
    fun()

    function fun(){
    alert('hello world')
    }
  • 函数表达式不能被提升,会报错 fun is not a function

    1
    2
    3
    4
    5
     fun()

    var fun = function fun(){
    alert('hello world')
    }
  • 函数优先提升,也就是变量声明的提升,无法覆盖函数的提升

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fun() // B

    var fun = function fun(){
    alert('A')
    }
    function fun(){
    alert('B')
    }
    fun() //A

  • 函数的参数

    1. 如果有一个参数没有收到值,则该形参为undefined,undefined进行任何运算的结果都为NaN

    2. arguments参数,相当于函数中默认的属性,可变的参数,接受到的实参列表,是一个类数组对象,可以像数组一样通过下表访问元素,但不能调用数组的方法,有length属性

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <script>
      function fun() {
      var sum = 0;
      for (var i = 0; i < arguments.length; i++) {
      sum += arguments[i];

      }

      console.log('所有的参数之和为:' + sum); //110
      }

      fun(33, 22, 55)
      </script>

    3. 函数的递归调用,要有终止递归的条件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <script>
      //书写一个函数 函数会自己调用自己 从而形成递归
      //函数的功能就是计算某个阶乘 n的阶乘就是n*(n-1)的阶乘
      function factorial(n) {
      //递归的出口 如果计算1的阶乘,可以不用递归了 直接告诉你答案1
      if (n == 1) return 1;
      //如果询问的不是1的阶乘就返回n*(n-1)!
      return n * factorial(n - 1);
      }

      var result = factorial(6);
      console.log(result); //720
      </script>

闭包

函数本身和该函数声明时所处环境状态的组合,函数能记忆住定义所处的环境,就是不在定义的环境中被调用,也能访问定义时所处的环境变量

也就是在函数中返回一个函数,返回的函数能访问到函数内部的变量,并在外部使用的时候优先调用函数内部的变量,相当于模拟私有变量

滥用闭包可能会导致内存泄漏问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
//创建一个函数
function fun() {
//定义局部变量
var name = '慕课网';
//返回一个局部函数
return function() {
alert(name)
}
}

//调用外部函数就能得到内部函数
var inner = fun();
//定义一个全局变量
var name = 'ABC';
//执行inn函数 就相当于在 fun函数的外部执行了内部的函数
inner()//这里弹出的就是慕课网
</script>

IIFE (立即执行函数)

函数必须要转换为函数表达式才能被调用如 ()(); +function(){}(); -function(){}(); 也可以用于命名函数

可以防止全局变量污染,代码模块化

箭头函数

属于表达式函数,不存在函数提升 ,只有一个参数时可以省略圆括号,只有一行代码省略花括号,并自动作为返回值返回

没有arguments动态参数,可以使用剩余参数

只会沿用自己作用域链上一级的this

深浅拷贝

  • 对于基本数据类型,拷贝实在内存中产生新的副本,比较的时候也是比较值是否相等

  • 对于引用数据类型,内存中不产生新的值,而是让新变量指向同一个对象,比较的时候也是比较内存地址是否相同

  • 当我们引用的对象内存地址是相同的时候,改变其中一个变量的值,另一个变量也会跟着改变

    解决方法:通过递归实现深拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    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)
    // 复习

    通过lodash实现深拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <!-- 先引用 -->
    <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>

    通过JSON对象实现深拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <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)

变量

  1. 局部变量,在函数或语句内部定义的,如果局部变量中的变量名和全局变量变量名相同,那在函数执行过程中,变量的值以局部变量为准
  2. 全局变量,不给变量加var 或 let 在函数中定义的也是全局变量(应该就是他的父类对象为window)

Web APIs

DOM(文档对象模型)

将文档表现为节点树,根为document对象,表示整个HTML文档

document对象

节点
访问元素节点的常用方法
方法 功能 兼容
document.getElementById() 通过id获取元素 IE6
document.getElementByTageName() 通过标签名获取元素 IE6
document.getElementByClassName() 通过类名获取 IE9
document.querySelector() 通过选择器获取 IE8部分
IE9
doocumentt.querySelectorAll() 通过选择器获取元素数组 IE8部分
IE9
节点之间的关系
  1. 改变节点中的元素内容可以用 innerHTMl innerText 这两个属性

  2. 改变元素节点的CSS样式,style.要改变的CSS属性 注意要写成驼峰的形式

  3. 创建新节点并插入,删除节点,只能通过父节点删除

    1
    2
    3
    4
    5
    const parent =  document.querySelector('div')
    const child = document.createAttribute('div')
    parent.appendChild(child) //在父元素的末尾添加子元素
    parent.insertBefore(child,parent.children[0])//在父元素的第一个子元素前添加子元素
    parent.removeChild(child)//删除子元素
事件
事件监听

事件:用户与网页的交互动作

1
2
3
4
5
6
7
8
<script>
var oBox = document.getElementById('box');
//给这个盒子添加点击事件监听
oBox.onclick = function() {
alert('你好,我是点击事件的函数');
}
</script>

  1. 常见的鼠标事件监听

    QQ_1735959416848
  2. 常见的键盘事件监听

    QQ_1735959439677
  3. 表单事件监听

    QQ_1735959466053
事件传播

从外到内在从内到外,JavaScript中分为捕获阶段和冒泡阶段,捕获阶段就是从外到内的过程,冒泡阶段就是从内到外的过程

  1. 有两种事件监听的方法
    • document对象.onclick DOM0级的事件,只能监听冒泡阶段,后面写的会覆盖前面写的
    • document对象.addEventListener(‘事件类型’,事件处理函数) DOM2级事件,会按顺序执行,匿名函数无法解绑
  2. 事件对象,事件处理函数中有一个对象,通常用e或event表示,可以通过这个对象定位到选择的元素
事件委托
QQ_1735960018747
定时器和延时器
定时器

setInterval 以固定时间重复调用一个函数,clearInterval这个方法清除定时器,定时器开启的时候可以用一个变量来接收

具体使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var a = 0;
//设置一个全局变量
var timer;

btn1.onclick = function() {
//为了防止定时器叠加 我们应该在设置定时器之前清除定时器
clearInterval(timer)
//更改全局变量的值为一个定时器实体
timer = setInterval(function() {
oInfo.innerText = ++a;
}, 1000)
}

btn2.onclick = function() {
clearInterval(timer)}
延时器

setTimeout 设置 指定时间会执行函数一次,clearTimeout清除延时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 const box = document.querySelector('.box')
let i = 1 // 让这个变量++
// 鼠标移动函数
function mouseMove() {
box.innerHTML = ++i
// 如果里面存在大量操作 dom 的情况,可能会卡顿
}
//fn为定义的函数,为定时的时间
function debounce(fn, t) {
let timeId
return function () {
// 如果有定时器就清除
if (timeId) clearTimeout(timeId)
// 开启定时器 200
timeId = setTimeout(function () {
fn()
}, t)
}
}
//mouseMove没有() ,因为它这里被当作了参数,而不是调用函数
box.addEventListener('mousemove', debounce(mouseMove, 200))

抛出异常和捕获异常
抛出异常
1
2
3
4
5
6
7
8
9
function fn(x, y) {
if (!x || !y) {
// throw '没有参数传递进来'
throw new Error('没有参数传递过来')
}

return x + y
}
console.log(fn())
try-catch语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function fn() {
try {
// 可能发送错误的代码 要写到 try
const p = document.querySelector('.p')
p.style.color = 'red'
} catch (err) {
// 拦截错误,提示浏览器提供的错误信息,但是不中断程序的执行
console.log(err.message)
throw new Error('你看看,选择器错误了吧')
// 需要加return 中断程序
// return
}
finally {
// 不管你程序对不对,一定会执行的代码
alert('弹出对话框')
}
console.log(11)
}
fn()
this的指向

谁调用就指向谁,注意有个父类对象window,像一些内置函数的指向就是它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 普通函数:  谁调用我,this就指向谁
console.log(this) // window
function fn() {
console.log(this) // window
}
window.fn()
window.setTimeout(function () {
console.log(this) // window
}, 1000)
document.querySelector('button').addEventListener('click', function () {
console.log(this) // 指向 button
})
const obj = {
sayHi: function () {
console.log(this) // 指向 obj
}
}
obj.sayHi()

具体实例

1
2
3
4
var arr = ['a', 'b', 'c', function () {
console.log(this[0])
}]
arr[3]()
改变this的指向

call 和 apply 的区别 call 用,罗列参数 apply用数组

  1. call函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const obj = {
    uname: 'pink'
    }
    function fn(x, y) {
    console.log(this) // window
    console.log(x + y) //NaN
    }
    // 1. 调用函数
    // 2. 改变 this 指向 改变后this就指代的是obj 对象
    fn.call(obj, 1, 2)
    // fn()
  2. apply函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    const obj = {
    age: 18
    }
    function fn(x, y) {
    console.log(this) // {age: 18}
    console.log(x + y)
    }
    // 1. 调用函数
    // 2. 改变this指向
    // fn.apply(this指向谁, 数组参数)
    fn.apply(obj, [1, 2])
    // 3. 返回值 本身就是在调用函数,所以返回值就是函数的返回值

    const arr = [100, 44, 77]
    const max = Math.max.apply(Math, arr) //100
    const min = Math.min.apply(null, arr) //44
    console.log(max, min)
    // 使用场景: 求数组最大值
    console.log(Math.max(arr));//NaN

    console.log(Math.max(...arr))// 100
  3. bind函数,和上面两个不同的是它的返回值是函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    const obj = {
    age: 18
    }
    function fn() {
    console.log(this)
    }

    // 1. bind 不会调用函数
    // 2. 能改变this指向
    // 3. 返回值是个函数, 但是这个函数里面的this是更改过的obj
    const fun = fn.bind(obj)
    // console.log(fun)
    fun()

    // 需求,有一个按钮,点击里面就禁用,2秒钟之后开启
    document.querySelector('button').addEventListener('click', function () {
    // 禁用按钮
    this.disabled = true
    window.setTimeout(function () {
    // 在这个普通函数里面,我们要this由原来的window 改为 btn
    this.disabled = false
    }.bind(this), 2000) // 这里的this 和 btn 一样
    })

BOM(浏览器对象模型)

浏览器中的每个标签页都有一个window对象,全局变量会成为window的属性,多个JS文件之间是共享作用域的,没有作用域隔离的功能,内置函数一般都是window的方法

浏览器窗口属性

1
2
3
4
console.log(window.innerHeight);//浏览器窗口高度
console.log(window.innerWidth);//浏览器窗口宽度
console.log(window.outerHeight);//浏览器窗口外部高度
console.log(window.outerWidth);//浏览器窗口外部宽度
  1. 窗口大小改变后会触发resize事件

    1
    2
    3
    4
    5
    window.onresize = function(){
    var root = document.documentElement;
    console.log(root.clientWidth); //窗口尺寸改变时,获取窗口宽度
    console.log(root.clientHeight); //窗口尺寸改变时,获取窗口高度
    }
  2. 获得卷积高度

    1
    2
    3
    4
    5
    6
    7
    //卷积事件监听
    window.scrollY //只读
    document.documentElement.scrollTop //可以改变
    window.onscroll = function(){
    console.log(document.documentElement.scrollTop);//窗口卷积高度
    console.log(document.documentElement.scrollLeft);//窗口卷积宽度
    }
  3. Navigator对象,包含用户使用浏览器的信息和操作系统

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    console.log(navigator.appCodeName); //浏览器代码名
    console.log(navigator.appName); //浏览器名称
    console.log(navigator.appVersion); //浏览器版本
    console.log(navigator.userAgent); //浏览器信息
    console.log(navigator.platform); //浏览器平台
    console.log(navigator.cookieEnabled); //是否启用cookie
    console.log(navigator.javaEnabled()); //是否启用java
    console.log(navigator.language); //浏览器语言
    console.log(navigator.onLine); //是否在线
    console.log(navigator.userAgentData); //浏览器信息
  4. History对象,模拟浏览器的回退按钮

    1
    2
    3
    4
    history.back(); //返回上一页
    history.forward(); //前进下一页
    history.go(-1); //返回上一页
    history.go(1); //前进下一页
  5. Location对象

    1
    2
    3
    4
    location.href = "https://www.baidu.com"; //跳转页面
    location.reload(true); //刷新页面,强制从服务器加载
    location.replace("https://www.baidu.com"); //替换页面
    location.assign("https://www.baidu.com"); //跳转页面

对象

键值对的集合,表示属性和值的映射关系

构造函数和原型对象中的this都指向实例化的对象

语法规则

  1. 定义一个对象

    1
    2
    3
    4
    5
    6
    var person = {
    firstName:"John",
    lastName:"Doe",
    age:50,
    eyeColor:"blue"
    };
  2. 访问当中的元素

    1
    2
    3
    person.lastName;
    person["lastName"];
    //但当属性名不符合规范的时候只能通过[]的形式访问、如果属性名以变量的方式存储也要用[]的形式访问
  3. 属性的赋值和新增

    使用赋值运算符,没有属性用创建的那个对象加点就会创建出这个属性

  4. 属性的删除

    1
    2
    3
    4
    5
    6
    var obj = {
    name: 'pink',
    age: 18
    }
    delete obj.name
    console.log(obj)
  5. 对象的遍历

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var obj = {
    name: 'pink',
    age: 18,
    sayHi: function () {
    console.log('hi')
    }
    }

    for (var key in obj) {
    console.log("key:" + key + " value:" + obj[key])
    }

new出来的对象

用new方法调用函数,函数内会自动创建出一个空白对象,函数中的this会指向这个对象,函数体内的语句会执行

会自己返回上下文对象,即使没有return语句

new 调用的函数也叫做构造函数,记得首字母大写(约定),构造函数通常是给对象赋值用的,如果不用new调用函数,它里面的this就不是本身

1
2
3
4
5
6
7
8
9
10
function Person(name, age) {
this.name = name
this.age = age
}
var p1 = new Person('pink', 18) // 构造函数
console.log(p1); // Person { name: 'pink', age: 18 }

var p2 = Person('pink', 18) // 普通函数
console.log(p2); // undefined

对象的原型链查找

任何函数都有prototype属性,该属性值是一个对象,默认有constructor属性指回函数

构造函数的prototype属性是它的实例的原型

实例可以通过.来访问原型的属性和方法

  1. 图解关系

  2. 代码实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function Star() {

    }
    const ldh = new Star()
    // 对象原型__proto__ 指向 改构造函数的原型对象
    console.log(ldh.__proto__)
    // console.log(ldh.__proto__ === Star.prototype)
    // 对象原型里面有constructor 指向 构造函数 Star
    console.log(ldh.__proto__.constructor === Star)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // function Objetc() {}
    console.log(Object.prototype) // {}
    console.log(Object.prototype.__proto__) // null

    function Person() {

    }
    const ldh = new Person()
    // console.log(ldh.__proto__ === Person.prototype)
    // console.log(Person.prototype.__proto__ === Object.prototype)
    console.log(ldh instanceof Person) // true
    console.log(ldh instanceof Object) // true
    console.log(ldh instanceof Array) // false
    console.log([1, 2, 3] instanceof Array) // true
    console.log(Array instanceof Object) // true

具体使用

如果将方法直接添加到实例身上会造成内存的浪费,每个实例和每个实例的方法函数都是内存中不同的函数,造成了内存的浪费

将方法添加到prototype就可以解决这个问题

  1. 通过原型链实现继承

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    // 继续抽取   公共的部分放到原型上
    // 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)

多级对象解构

只取出我们需要的数据 {}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 1. 这是后台传递过来的数据
const msg = {
"code": 200,
"msg": "获取新闻列表成功",
"data": [
{
"id": 1,
"title": "5G商用自己,三大运用商收入下降",
"count": 58
},
]
}

// 需求1: 请将以上msg对象 采用对象解构的方式 只选出 data 方面后面使用渲染页面
// const {data} = msg
// console.log(data);
// 需求2: 上面msg是后台传递过来的数据,我们需要把data选出当做参数传递给 函数

// function render({data}) {
// // 我们只要 data 数据
// // 内部处理
// console.log({data});

// }
// render(msg)

// 需求3, 为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为 myData
function render({data:myData}) {
// 要求将 获取过来的 data数据 更名为 myData
// 内部处理
console.log({myData})
}
render(msg)

包装类

  1. 数组 Array

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    const arr = [
    {
    name: '小米',
    price: 1999
    },
    {
    name: '华为',
    price: 3999
    },
    ]
    // 找小米 这个对象,并且返回这个对象
    // const mi = arr.find(function (item) {
    // // console.log(item) //
    // // console.log(item.name) //
    // console.log(111)
    // return item.name === '华为'
    // })
    // 1. find 查找 放回的是找到的对象
    const mi = arr.find(item => item.name === '小米')
    // console.log(mi)
    // 2. every 每一个是否都符合条件,如果都符合返回 true ,否则返回false
    const arr1 = [10, 20, 30]
    const flag = arr1.every(item => item >= 20)

    // 求和
    const arr = [1, 2, 3]
    const re = arr.reduce((prev, item) => prev + item)
    // 过滤 返回一个新数组
    const re1 = arr.filter(item => item > 2)
    arr.push(4) // 添加
    arr.pop() // 删除
    arr.shift() // 删除第一个
    arr.unshift(1) // 添加第一个
    arr.splice(1, 1) // 删除
    arr.splice(1, 0, 2) // 添加
    console.log(re)
    console.log(re1)
    arr.forEach(item => {
    console.log(item)
    })
    // 映射 返回一个新数组
    const re2 = arr.map(item => {
    return item * 2
    })


    // Array.from(lis) 把伪数组转换为真数组
    const lis = document.querySelectorAll('ul li')
    // console.log(lis)
    // lis.pop() 报错
    const liss = Array.from(lis)
    liss.pop()
    console.log(liss)

  2. 日期类 Data

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const date = new Date()
    console.log(date.getFullYear()); // 年
    console.log(date.getMonth() + 1); // 月
    console.log(date.getDate()); // 日
    console.log(date.getHours()); // 时
    console.log(date.getMinutes()); // 分
    console.log(date.getSeconds()); // 秒
    console.log(date.getDay()); // 星期
    console.log(date.getTime()); // 时间戳

正则表达式

匹配字符串中字符组合的模式

常用方法

1
2
3
4
5
6
7
8
const regObj = /a/g
const str = "abc"
console.log(regObj.test(str)); // 判断字符串是否匹配正则表达式
console.log(regObj.exec(str)); // 返回匹配到的第一个值
console.log(str.match(regObj)); // 返回匹配到的所有值
console.log(str.replace(regObj, "b")); // 替换匹配到的所有值
console.log(str.search(regObj)); // 返回匹配到的第一个值的索引
console.log(str.split(regObj)); // 返回匹配到的所有值的数组

修饰符

  • i 忽略大小写

  • g 全局匹配

  • m 多行匹配

  • u 匹配unicode编码

  • y 匹配开始位置