一、 作用域
作用域(scope) = 全局作用域(Global) + 局部作用域(Local) ;局部作用域 = 函数作用域 + 块作用域 ;作用域: 规定了变量 能够 被访问 的 范围 ,离开了这个范围,变量便不能被访问;
1.1 局部作用域
Local
局部作用域 = 函数作用域 + 块作用域 ;
1.1.1 函数作用域
⚠ 注意:
在 函数内部 声明的 变量 只能在 函数内部 被 访问 ,外部 无法直接访问(可以利用闭包来访问); 函数 的 参数 也是 函数内部 的 局部变量 ;不同函数 内部声明 的 变量 无法 互相访问; ⚠ 函数执行完毕后,函数内部的变量实际被清空了(JS垃圾回收机制);
1.1.2 块作用域
在JavaScript中使用 {}
包裹的 代码 称为 代码块 ,代码块内部 声明的变量 外部【有可能:var声明的可以】无法访问;
⚠ 注意:
⚠ let
和 const
声明的变量 会产生 块作用域 ; ⚠ var
🔺不会产生🔻 块作用域 :
不同代码块之间 的 变量 无法 互相访问; 推荐使用 let
或 const
;
1.2 全局作用域
Global
⚠ 注意:
为 window
对象 动态添加的 属性 默认 是 全局变量,不推荐!; 函数中 未使用 任何关键字 声明的 变量 是 全局变量,不推荐!!!; 尽可能减少声明全局变量,防止变量污染;
1.3 作用域链
1.4 JS垃圾回收机制 - GC
JS中 内存的分配 和 回收 都是 自动完成 的,内存 不使用 的时候 会被 垃圾回收器 自动回收 ;
内存的生命周期 :
1️⃣ 内存分配: 声明 变量 、函数 、对象 的时候,系统会 自动 为它们 分配内存 ; 2️⃣ 内存使用: 既 读写内存 ,也就是 使用 变量、函数等; 3️⃣ 内存回收: 使用完毕,由垃圾回收器 自动回收 不再使用的内存 ; ⚠ 注意:
全局变量 一般 不会回收 (关闭页面回收)⚠ 一般情况下 局部变量 的值,不用了 ,就会被自动回收 垃圾回收算法说明:
1️⃣❌ 引用计数法
致命缺陷:嵌套引用 如果两个对象相互引用,尽管他们不再使用,垃圾回收器不会进行回收,导致内存泄漏 2️⃣ 标记清除法
1.5 ❗❗ 闭包
闭包:Closure
概念: 一个函数 对 周围状态的引用 捆绑在一起,内层函数 能够访问到 其外层函数 的 作用域;
闭包是一种使用过程; 闭包 = 内层函数 + 外层函数的变量 ; 代码展示:function fn ( ) {
let b = 9 ;
function outer ( ) {
const a = 1 ;
console. log ( b) ;
function f ( ) {
console. log ( a) ;
console. log ( b) ;
}
f ( ) ;
}
outer ( ) ;
}
fn ( ) ;
函数套函数 不一定会 产生 闭包 如果 内层函数 用到 外层函数 的 变量 这种情况就 会产生闭包 ⚠ 闭包使用注意: 闭包使用的时候,内部的变量因为被外部引用了,所以代码执行完毕不会释放内存 - 内存泄漏(引用计数法) ❗ 闭包作用:
实现数据的私有化 外部 可以 访问 函数内部 的 变量 允许将 函数 与其所操作的 某些数据(环境)关联起来 应用场景 :
基本格式:function fn ( ) {
let b = 9 ;
function outer ( ) {
const a = 1 ;
console. log ( b) ;
function f ( ) {
let c = 6 ;
console. log ( a) ;
console. log ( b) ;
}
return f;
}
return outer;
}
const fun = fn ( ) ;
fun ( ) ;
const fun1 = fun ( ) ;
fun1 ( ) ;
闭包应用: 实现 数据 的 私有化;
❗❗ 闭包面试:怎么理解闭包 -> 闭包的作用 -> 闭包可能引起的问题
1.6 ❌ 变量提升
二、函数进阶
2.1 函数提升
2.2 函数参数
2.2.1 动态参数
arguments: 函数内部 内置 的 伪数组变量 ,包含了 调用 函数时 传入 的 所有实参 只能在普通函数里使用 作用: 动态获取函数的实参⚠ 注意:
表示 所有实参 的 集合 arguments 是一个 伪数组 , 只存在于 函数内部 箭头函数 🔺没有🔺 arguments 🔺 可读写 代码展示:
function getSum ( ) {
let sum = 0 ;
for ( let i = 0 ; i < arguments. length; i++ ) {
sum += arguments[ i] ;
}
return sum;
}
console. log ( getSum ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ) ) ;
2.2.2 ✔ 剩余参数
允许将一个 不定数量 的 参数 表示为一个 数组 … 是语法符号,置于 最末 函数形参 之前,用于获取 剩余 (多于) 的实参⚠ 注意:
借助 … 获取的 剩余实参 ,是个真数组 剩余参数放在 最末位 如果 没有剩余的参数 ,得到的就是一个 空数组 代码展示:
function getSum ( ... arr) {
console. log ( arr) ;
}
getSum ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ) ;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
function getSum ( a, b, c, ... arr ) {
console. log ( arr) ;
}
getSum ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ) ;
动态参数 和 剩余参数 的区别:
拓展:
展开运算符: (… )
展开运算符将一个 数组 、对象 展开
当你在 函数的实参 或者 数组 或者 对象 里面使用的时候是 展开运算符 展开运算符写在数组前面 应用场景:
用于获取数组的最大值 合并数组 解构赋值(部分场景)
解构赋值 中 展开运算符 只能写在 最后一个元素 的 前面 展开运算符 or 剩余参数 展开运算符: 数组 中使用,数组展开 ,在 数组内部 使用剩余参数: 函数参数 使用,得到真数组 ,在 函数内部 使用代码展示:
const arr = [ 3 , 45 , 2 , 89 , 54 ] ;
console. log ( ... arr) ;
console. log ( Math. max ( ... arr) ) ;
const arr1 = [ 1 , 2 , 4 ] ;
const arr2 = [ ... arr, ... arr1] ;
console. log ( arr2) ;
const [ n1, n2, ... n3] = [ 1 , 2 , 3 , 4 , 5 ] ;
console. log ( n1, n2, n3) ;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
const [ n1, ... n2, n3] = [ 1 , 2 , 3 , 4 , 5 ] ;
2.3 ❗❗❗ 箭头函数
⚠🔺 注意:
箭头函数 没有 arguments ,但是 有 剩余参数 箭头函数 没有 this 箭头函数 替代原本需要 匿名函数 的地方函数表达式 的 简写方式 (匿名函数) 声明式函数 不能写
2.3.1 基本语法
2.3.2 箭头函数参数
2.3.3 箭头函数 this
函数 才有this 以前的this指向:
console. log ( this ) ;
function fn ( ) {
console. log ( this ) ;
}
fn ( ) ;
const obj = {
uname : '迪迦奥特曼' ,
sayHi : function ( ) {
console. log ( this ) ;
}
}
obj. sayHi ( ) ;
window 是JS中的全局对象,我们 声明 的 变量 或 函数 实际上是给 window 添加 属性 或 方法 箭头函数 不会创建 自己的this,它只会 沿用 自己所在这条作用域链 的 上一层作用域 的 this
箭头函数的 this指向被创建的时候上下文中的this(出生的时候,所在的作用域中的this是谁,以后就都指向谁) 箭头函数里面的 this 任何方法都改变不了
因为箭头函数没有 this (它用的是上一层作用域链的 this ) call / apply / bind 不能改变 代码展示:
const fn = ( ) => console. log ( this ) ;
fn ( ) ;
const obj = {
uname : '迪迦奥特曼' ,
sayHi : ( ) => console. log ( this )
}
obj. sayHi ( ) ;
const obj1 = {
uname : '迪迦奥特曼' ,
sayHi : function ( ) {
let i = 10 ;
const count = ( ) => console. log ( this ) ;
count ( ) ;
}
}
obj1. sayHi ( ) ;
三、❗❗ 解构赋值
3.1 数组解构
3.1.1 基本语法
数组解构: 是 将数组的 单元值(数组元素) 快速 批量赋值 给 一系列变量 的 简介语法 基本语法:
赋值运算符 = 左侧 的 []
用于 批量 声明变量 ,右侧数组 的 单元值 将被 赋值给左侧的变量 变量的顺序 对应 数组单元值的位置 依次 进行 赋值操作 ⚠🔺 注意: 数组解构 赋值 是按照 索引 赋值 的 代码展示:
const [ a, b, c] = [ 1 , 2 , 3 ] ;
console. log ( a) ;
console. log ( b) ;
console. log ( c) ;
利用数组解构交换两个变量的值let a = 11 ;
let b = 22 ;
[ b, a] = [ a, b] ;
console. log ( a)
console. log ( b)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
let a = 11
let b = 22
[ b, a] = [ a, b]
console. log ( a)
console. log ( b)
3.1.2 特殊情况
1️⃣ 变量多 单元值少
右侧的单元值按顺序对左侧的变量进行赋值,没有赋值的变量则是 undefined 代码展示:const [ hr, lx, mi, fz, hw] = [ '海尔' , '联想' , '小米' , '方正' ] ;
console. log ( hr, lx, mi, fz, hw) ;
2️⃣ 变量少 单元值多
右侧的单元值按顺序对左侧的变量进行赋值,剩余的单元值丢弃不用 代码展示:const [ hr, lx, mi] = [ '海尔' , '联想' , '小米' , '方正' ] ;
console. log ( hr, lx, mi) ;
3️⃣ 利用 剩余参数 解决 变量少 的问题
⚠ 注意:
剩余参数 返回的是一个真数组 剩余参数 放在 最末位 代码展示:const [ hr, lx, ... mi] = [ '海尔' , '联想' , '小米' , '方正' ] ;
console. log ( hr, lx, mi) ;
4️⃣ 防止 undefined 传递
设置默认值 代码展示:const [ hr, lx, mi, fz, hw = '华为' ] = [ '海尔' , '联想' , '小米' , '方正' ] ;
console. log ( hr, lx, mi, fz, hw) ;
5️⃣ 按需导入,忽略某些值
⚠ 变量可以忽略,但是位置还是要留的 代码展示:const [ hr, lx, mi, , hw = '华为' ] = [ '海尔' , '联想' , '小米' , '方正' ] ;
console. log ( hr, lx, mi, hw) ;
6️⃣ 多维数组解构
代码展示:const [ a, [ b, [ c, d, [ e] ] ] , f] = [ 1 , [ 2 , [ 3 , 4 , [ 5 ] ] ] , 6 ] ;
console. log ( a, b, c, d, e, f) ;
3.2 对象解构
对象解构: 是 将对象 属性 和 方法 快速 批量赋值 给一些列 变量 的 简介语法
3.2.1 基本语法
3.2.2 特殊情况
1️⃣ 对象解构的变量名 可以重新声明
⚠语法: 旧变量名: 新变量名 代码展示:const uname = '赛罗奥特曼' ;
const { uname : username, age } = { uname : '迪迦奥特曼' , age : 22 } ;
console. log ( username, age) ;
2️⃣ 解构数组对象
代码展示:const obj = [
{
uname : '迪迦奥特曼' ,
age : 22
} ,
{
uname : '赛罗奥特曼' ,
age : 23
}
] ;
const [ { uname, age } , { uname : userName, age : userAge } ] = obj;
console. log ( uname, age, userName, userAge) ;
3️⃣ 多级对象解构
⚠ 解构的时候必须写 🔺对象名🔺 ,不能打印 代码展示:const pig = {
name : '佩奇' ,
family : {
mother : '猪妈妈' ,
father : '朱爸爸' ,
sister : '乔治'
} ,
age : 6
} ;
const { name, family : { mother, father, sister } , age } = pig;
console. log ( name, mother, father, sister, age) ;
const person = [
{
name : '佩奇' ,
family : {
mother : '猪妈妈' ,
father : '朱爸爸' ,
sister : '乔治'
} ,
age : 6
}
] ;
const [ { name, family : { mother, father, sister } , age } ] = person;
console. log ( name, mother, father, sister, age) ;
✔✔
const msg = {
"code" : 200 ,
"msg" : "获取新闻列表成功" ,
"data" : [
{
"id" : 1 ,
"title" : "5G商用自己,三大运用商收入下降" ,
"count" : 58
} ,
{
"id" : 2 ,
"title" : "国际媒体头条速览" ,
"count" : 56
} ,
{
"id" : 3 ,
"title" : "乌克兰和俄罗斯持续冲突" ,
"count" : 1669
} ,
]
} ;
const { data } = msg;
console. log ( data) ;
function render ( { data } ) {
console. log ( data) ;
}
render ( msg) ;
function render ( { data : myData } ) {
console. log ( myData) ;
}
render ( msg) ;
今日案例拓展:
:active
伪类选择器
draggable
可拖拽的
draggable ="false"
禁止拖拽draggable ="true"
可以拖拽
四、对象进阶
4.1 创建对象的三种方式
4.2 构造函数(自封装)
是一种 特殊的函数,主要用来 初始化对象 可以用构造函数 创建多个 类似 对象 (对公共的部分进行抽取并封装) 规范:
命名以 大写字母 开头 ⚠🔺 只能由 new 操作符来执行 ⚠🔺 注意:
使用 new 关键字调用函数的行为被称为 实例化 构造函数内部 无需写return ,返回值 即为 新创建的对象 构造函数内部的 return 返回的值 无效 ,所以不要写 return ❗❗ 实例化执行的过程: (面试)
1️⃣ 创建新的 空对象 2️⃣ 构造函数 this 指向 新对象 3️⃣ 执行构造函数代码,修改this,添加新属性 4️⃣ 返回新对象 代码展示:
4.3 实例成员 & 静态成员
4.3.1 实例成员
构造函数 创建的 对象 称为 实例对象 🔺 实例对象 的 属性 和 方法 称为 实例成员 ⚠ 注意:
为 构造函数 传入 参数,动态创建 结构相同 但 值不同 的 对象 构造函数 创建 的 实例对象 彼此独立 互不影响
4.3.2 静态成员
🔺 构造函数 的 属性 和 方法 被称为 静态成员 ⚠🔺 静态成员方法 中的 this 指向 构造函数 一般 公共特征 的属性或方法 静态成员设置为静态成员
五、内置构造函数 - Object
字符串、数值、布尔等基本数据类型也都有专门的构造函数,称为 基本包装类型 引用类型: Object、Array、RegExp、Date 等包装类型: String、Number、Boolean 等
5.1 ❌用内置构造函数创建对象
const obj = new Object ( { uname : '迪迦' , age : 22 } ) ;
5.2 常用的 静态方法
静态方法: 只有 构造函数 Object 才可以 调用 (写在构造函数身上的方法)
5.2.1 Object.keys()
作用 :
语法: Object. keys ( 对象名)
⚠ 返回值:
代码展示:⬇
5.2.2 Object.values()
作用 :
语法: Object. values ( 对象名)
⚠ 返回值:
代码展示:⬇
5.2.3 Object.assign()
5.2.4 代码展示
const obj = { uname : '迪迦' , age : 22 } ;
const arr = Object. keys ( obj) ;
console. log ( arr) ;
const arr1 = Object. values ( obj) ;
console. log ( arr1) ;
const obj1 = { } ;
Object. assign ( obj1, obj) ;
console. log ( obj1) ;
Object. assign ( obj1, { gender : '男' } ) ;
console. log ( obj1) ;
六、内置构造函数 - Array
6.1 ❌使用Array内置构造函数创建数组
const arr = new Array ( ) ;
const arr = new Array ( 5 ) ;
const arr = new Array ( 1 , 2 , 3 , 4 , 5 ) ;
6.2 数组方法总结 - 改变原始数组 (7)
6.2.1 push()
作用 :
将 一个或多个元素 追加到 数组的末尾 ,并返回 追加元素之后 数组的 length 语法 :arr. push ( val1, ... , valN) ;
返回值 :
代码展示:const arr = [ 1 , 2 , 3 ] ;
const length = arr. push ( 4 , 5 ) ;
console. log ( arr) ;
console. log ( length) ;
6.2.2 unshift()
作用 :
将 一个或多个元素 插入到 数组的开头 ,并返回 插入元素之后 数组的 length 语法 :arr. unshift ( val1, ... , valN) ;
返回值 :
代码展示:const arr = [ 3 , 4 , 5 ] ;
const length = arr. unshift ( 1 , 2 ) ;
console. log ( arr) ;
console. log ( length) ;
6.2.3 pop()
6.2.4 shift()
6.2.5 splice()
作用 :
通过 删除 或 替换 现有元素 或 原地添加新元素 来 修改数组 ,并以 数组的形式返回被修改的内容 语法 :array. splice ( startIndex[ , deleteCount[ , items] ] )
返回值 :
⚠ 注意 :
删除/替换 的时候,包括 开始索引 的 位置 添加 的时候,是添加在 开始索引位置之前 添加 的时候返回的是 空数组 代码展示:
const arr = [ 1 , 2 , 3 ] ;
const Value = arr. splice ( 1 , 1 ) ;
console. log ( arr) ;
console. log ( Value) ;
const arr = [ 1 , 2 , 3 ] ;
const Value = arr. splice ( 1 , 1 , 6 ) ;
console. log ( arr) ;
console. log ( Value) ;
const arr = [ 1 , 2 , 3 ] ;
const Value = arr. splice ( 1 , 0 , 8 ) ;
console. log ( arr) ;
console. log ( Value) ;
6.2.6 sort() - 数组排序
作用 :
语法 :arr. sort ( ) 可以省略参数,升序
arr. sort ( function ( a, b ) { return a - b } ) 升序排列
arr. sort ( function ( a, b ) { return b - a } ) 降序排列
返回值 :
代码展示:const arr = [ 23 , 45 , 78 , 10 ] ;
arr. sort ( ) ;
console. log ( arr) ;
arr. sort ( function ( a, b ) { return a - b} ) ;
console. log ( arr) ;
arr. sort ( function ( a, b ) { return b - a} ) ;
console. log ( arr) ;
6.2.7 reverse() - 反转数组
作用 :
语法 :arr. reverse ( ) ;
返回值 :
代码展示:const arr = [ 1 , 2 , 3 , 4 , 5 ] ;
arr. reverse ( ) ;
console. log ( arr) ;
6.3 数组方法总结 - 不改变原始数组
6.3.1 forEach - 遍历数组
作用 :
语法 :Array. forEach ( function ( item[ , index[ , Array] ] ) { } )
返回值 :
代码展示:const arr = [ 'red' , 'purple' , 'pink' ] ;
arr. forEach ( ( item, index ) => {
console. log ( item) ;
console. log ( index) ;
} ) ;
6.3.2 map() - 迭代数组(映射数组)
作用 :
遍历原数组,把原数组中的每一个数据加工改造,形成一个新数组返回 语法: Array. map ( function ( item[ , index[ , Array] ] ) { } )
返回值 :
注意 :
将原始数组里面的元素进行处理之后添加到新数组里 新数组length = 旧数组length 代码展示:const arr = [ 'red' , 'blue' , 'green' ] ;
const newArr = arr. map ( function ( item, index, arr ) {
return item + '老师' ;
} ) ;
console. lgo ( newArr) ;
const arr1 = [ 10 , 20 , 30 ] ;
const newArr1 = arr1. map ( function ( item, index, arr ) {
return item + 10 ;
} ) ;
console. log ( newArr1) ;
6.3.3 filter() - 筛选数组
作用 :
过滤 原始数组中的数据,把 满足条件 的数据放在一个新数组中 语法 :Array. filter ( function ( item[ , index[ , Array] ] ) { } )
返回值 :
是一个新数组,里面是所有原始数组中满足条件的数据 注意 : 在执行函数返回true 的情况下,留下该数据 ,返回为false 去除该数据 ; 代码展示:const arr = [ 20 , 1 , 34 , 60 , 49 , 90 , 200 , 288 ] ;
const newArr = arr. filter ( item => {
return item > 100 ;
} ) ;
console. log ( newArr) ;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
const arr = [ 23 , 4 , 19 , 22 , 56 , 77 ] ;
const newArr = arr. filter ( item => {
if ( item % 2 === 0 ) {
return true ;
} else {
return false ;
}
} ) ;
console. log ( newArr) ;
const newArr = arr. filter ( item => item % 2 === 0 ) ;
console. log ( newArr) ;
6.3.4 reduce() - 累计器(求和)
作用 :
每一次运行 reduce 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值 语法 :Array. reduce ( function ( ) { } , 起始值)
Array. reduce ( function ( 累计值, 当前元素[ , 索引号] [ , 原数组] ) { } [ , 起始值] )
参数 :
起始值可以省略
如果写就作为第一次累计的起始值 如果没有,就取第一个元素作为起始值(累加的时候从第二个元素开始) 有起始值,则以起始值为准开始累计,累计值 = 起始值 没有起始值,则累计值以数组的第一个元素作为起始值开始累计 后面每次遍历就会用后面的数组元素 累计 到 累计值 里面 返回值 :
代码展示:
const arr = [ 1 , 2 , 3 , 4 , 5 ] ;
const sum = arr. reduce ( ( prev, item ) => prev + item, 0 ) ;
console. log ( sum) ;
const sum = arr. reduce ( ( prev, item ) => prev + item) ;
console. log ( sum) ;
6.3.5 join()
6.3.6 find() - 返回数组中满足条件的 第一个元素
作用 :
语法 :Array. find ( function ( item, index, arr ) { } [ , thisArg] )
返回值 :
有 满足条件 元素: 返回 第一个 元素 没有 这个元素: undefined 代码展示:const arr = [ 5 , 12 , 8 , 130 , 44 ] ;
const found = arr. find ( item => item > 10 ) ;
console. log ( found) ;
6.3.7 some()
作用 :
语法 :Array. some ( function ( item, index[ , arr] ) { } )
返回值 :
布尔值(true / false) 有 一个 满足 - true 都不 满足 - false 代码展示:const arr = [ 1 , 2 , 3 , 4 , 5 ] ;
const value = arr. some ( item => item >= 3 ) ;
console. log ( value) ;
6.3.8 every()
描述: 判断 数组 里面的 每一个元素 是不是都 满足条件 语法: Array. every ( function ( item, index[ , arr] ) { } )
返回值: 布尔值(true / false)
都满足 - true 有 一个 不满足 - false 代码展示:const arr = [ 2 , 26 , 56 , 34 , 67 ] ;
let flag = arr. every ( item => item > 30 ) ;
console. log ( flag) ;
6.3.9 concat() - 合并数组
作用 :
合并 两个或多个数组。此方法不会更改现有数组,而是返回一个 新数组 语法 :const new_array = oldArr. concat ( value1[ , value2[ , ... [ , valueN] ] ] )
参数 :
返回值 :
代码展示:
const arr = [ 1 , 2 , 3 ] ;
const arr1 = [ 4 , 5 , 6 ] ;
const new_array = arr. concat ( arr1) ;
console. log ( new_array) ;
const num = 8 ;
const new_array = arr. concat ( num) ;
console. log ( new_array) ;
const obj = { uname : '奥特曼' , age : 22 } ;
const new_array = arr. concat ( obj) ;
console. log ( new_array) ;
6.3.10 slice() - 提取元素
作用 :
语法 :Array. slice ( 开始索引, 结束索引)
⚠ 参数 :
包前不包后 第一个参数不写: 头 ➡ 指定位置 第二个参数不写: 指定位置 ➡ 尾 参数可以是一个负数 -> length + 负数 返回值 :
代码展示:const arr = [ 1 , 2 , 3 , 4 , 5 , 6 ] ;
const newArr = arr. slice ( 2 , 4 ) ;
const newArr = arr. slice ( 4 ) ;
const newArr = arr. slice ( 2 ) ;
const newArr = arr. slice ( 2 , - 2 ) ;
const newArr = arr. slice ( ) ;
console. log ( newArr) ;
6.3.11 flat() - 数组降维(数组扁平化)
arr. flat ( 几维数组) ;
arr. flat ( Infinity ) ;
6.3.12 indexOf() - 正向 查看数组里面 指定数据 的 索引
Array. indexOf ( 数据)
Array. indexOf ( 数据, 开始索引) 从哪个索引开始向后查找
返回值: 如果有这个数据,是第一个满足条件的数据的索引
如果没有这个数据,就是 - 1
6.3.13 lastIndexOf() - 反向 查看数组里面 指定数据 的 索引
Array. lastIndexOf ( 数据)
Array. lastIndexOf ( 数据, 开始索引)
注意: 虽然是反向查找,但是索引还是正常索引
6.3.14 copyWithin() - 使用 数组里面的内容 替换 数组里面的内容
Array. copyWithin ( 目标位置, 开始索引, 结束索引)
- > 目标位置:当你替换内容的时候,从哪一个索引位置开始替换
- > 开始索引:数组哪一个索引位置开始当作替换内容,默认是 0
- > 结束索引:数组哪一个索引位置结束当作替换内容,默认是 结尾
返回值: 是一个新数组(替换后的数组)
6.3.15 fill() - 使用 指定数据区 填充 数组
Array. fill ( 要填充的数据, 开始索引, 结束索引)
前提: 数组要有 length
返回值:
填充好的数组
6.3.16 includes() - 查看 数组中是不是有 某一个数据
Array. includes ( 数据)
返回值: 一个布尔值
有这个数据就是 true
没有这个数据就是 false
6.3.17 findIndex() - 根据条件找到数组里面满足条件的数据的索引
Array. findIndex ( function ( item ) { } )
返回值:
找到满足条件的第一个元素的索引
6.4 伪数组 ➡ 真数组
七、 内置构造函数 - String
7.1 ❌字符串的创建
let str = 'hello world'
let str = new String ( 'hello world' )
7.2 字符串方法
都是 实例方法 ⚠ 注意 :
7.2.1 substring() - 截取字符串
语法: str. substring ( indexStart[ , indexEnd] )
参数:
indexStart = indexEnd ➡ 返回一个 空字符串 省略indexEnd ➡ 提取字符 开始索引 一直 到 字符串末尾 如果任一 参数小于0或为NaN ,则被 当作 0 如果任一 参数大与 stringName.length ,则被当作 stringName.length 如果 indexStart 大与 indexEnd ,则substring 的执行结果就像两个参数调换了一样。 返回值 :
⚠ 注意:
包前 不包后 ;能取到开始索引位置的字符,取不到结束索引位置的字符; 代码展示:
const str = '迪迦奥特曼,塞罗奥特曼,银河奥特曼,艾克斯奥特曼' ;
const newStr = str. substring ( 4 , 9 ) ;
const newStr = str. substring ( 6 ) ;
const newStr = str. substring ( 6 , 6 ) ;
const newStr = str. substring ( - 9 ) ;
const newStr = str. substring ( NaN ) ;
const newStr = str. substring ( 100 ) ;
const newStr = str. substring ( 9 , 4 ) ;
console. log ( newStr) ;
❌ 拓展:也是截取字符串的方法
7.2.2 split() - 将 字符串 拆分成 数组 (分割)
语法: str. split ( 分隔符)
参数:
字符串里面用的什么分隔符参数就是什么 没有参数 / 别的字符: 数组里面的 元素 就是 字符串本身 空字符串: 将字符串的每一个 字母 或 数组 或 文字 或 标点符号 都作为一个 数组元素 返回值: 数组注意: 和 数组的join方法 相反代码展示:
const str = '迪迦奥特曼,塞罗奥特曼,银河奥特曼,艾克斯奥特曼' ;
const arr = str. split ( ',' ) ;
console. log ( arr) ;
const str1 = '2022-8-16' ;
const arr1 = str1. split ( '-' ) ;
console. log ( arr1) ;
7.2.3 startsWith() - 检测是否以某个(某段)字符开头
语法: string. startsWith ( 检测字符串[ , 检测位置索引号] )
参数:
返回值: 布尔值(true / false) ⚠ 注意:
代码展示:
const str = '迪迦奥特曼,赛罗奥特曼,银河奥特曼,艾克斯奥特曼' ;
const flag = str. startsWith ( '赛罗奥特曼' , 6 ) ;
console. log ( flag) ;
7.2.4 includes() - 判断一个字符串是否包含在另一个字符串中(返回true / false
)(includes
- 包含)
语法: str. includes ( 搜索的字符串[ , 检测索引位置] )
返回值: true / false
代码展示:
const str = '迪迦奥特曼,赛罗奥特曼,银河奥特曼,艾克斯奥特曼' ;
const flag = str. includes ( '赛罗奥特曼' ) ;
console. log ( flag) ;
7.2.5 replace() - 替换字符串中指定的字符
语法: 字符串. replace ( 要替换的旧字符, 替换的新字符)
返回值: 替换之后 的字符串注意:
不改变 原始字符串默认 只替换 匹配到的 第一个字符串 可以 配合 正则表达式(g 和 i) 来 全局匹配 并且 不区分大小写 代码展示:let str = '赛文奥特曼真好看,并且赛文奥特曼真厉害!' ;
const newStr = str. replace ( / 赛文 / g , '迪迦' ) ;
console. log ( newStr) ;
八、内置构造函数 - Number
九、编程思想
9.1 面向过程变成
面向过程: 就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用就可以了优点:
性能 比面向对象 高 ,适合跟硬件联系很紧密的东西,例如单片机 缺点:
9.2 面向对象编程 (oop)
面向对象: 是把事务分解成为一个个对象,然后由对象之间分工与合作。
特性:
优点:
易维护、易复用、易扩展,基于面向对象封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护 缺点:
十、构造函数
构造函数 体现了 面向对象 的 封装特性 构造函数 实例创建 的 对象 彼此独立、互不影响 构造函数存在的问题:浪费内存(可以用原型解决) 代码展示:
function Star ( uname, age, gender ) {
this . uname = uname;
this . age = age;
this . gender = gender;
this . sing = function ( ) { console. log ( '构造函数' ) ; }
}
const dj = new Star ( '迪迦' , 22 , '男' ) ;
const sl = new Star ( '赛罗' , 23 , '女' ) ;
console. log ( dj === sl) ;
console. log ( dj. sing === sl. sing) ;
十一、❗❗❗ 原型
11.1 原型
原型
是一个 对象 ,我们称 prototype 为 原型对象 跟随函数一起创建的对象 构造函数 通过 原型 分配的 方法 是 所有对象 所 共享的 js规定,每一个 构造函数 都有一个 prototype 属性,指向 另一个对象 ,所以我们称为 原型对象 这个原型对象可以挂载函数,对象实例化不会多次创建原型上函数,节约内存
可以把那些不变的方法,直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法 作用: 为当前函数创建的实例添加公共的属性和方法(把那些不变的方法挂载在prototype上)⚠🔺 构造函数 和 原型对象 中的 this 都指向 实例对象
原型上的方法,谁调用就指向谁(实例对象 + 原型自己) 有函数 就有 原型对象 代码展示:
function Star ( uname, age, gender ) {
this . uname = uname;
this . age = age;
this . gender = gender;
}
const Dj = new Star ( '迪迦' , 22 , '男' ) ;
const Sl = new Star ( '赛罗' , 23 , '女' ) ;
Star . prototype. sing = function ( ) { console. log ( '原型-prototype' ) ; }
console. log ( Dj. sing === Sl. sing) ;
Star . prototype. sing ( ) ;
const arr = [ 6 , 3 , 8 , 2 , 9 , 0 ] ;
Array . prototypeGgetValue = function ( ) {
return [ Math. max ( ... this ) , Math. min ( ... this ) , this . reduce ( ( prev, item ) => prev + item) ]
}
console. log ( arr. GetValue ( ) ) ;
11.2 constructor属性
每个 原型对象 里面都有 constructor 属性(constructor ➡ 构造函数) 作用: 该属性 指向 该原型对象 的 构造函数
⚠🔺 每个 构造函数 都有 prototype属性 ,每个 prototype属性 都有 constructor属性
使用场景:
如果有 多个对象 的 方法 ,我们可以 给 原型对象 采用 对象形式 赋值 (单个方法是追加 ) 但是这样就会 覆盖 构造函数 原型对象 原来 的 内容 ,这样 修改后 的 原型对象 的constructor属性 就 不再 指向 当前 构造函数 此时,我们可以在 修改后 的 原型对象 中,添加一个 constructor属性 指向 原来的构造函数 代码展示:
原来的prototype:
11.3 对象原型
对象 都会有一个 __proto__
指向 构造函数 的 prototype 原型对象 ,之所以我们对象可以使用构造函数 prototype 原型对象的属性和方法,就是因为对象有 __proto__
原型的存在
⚠ 注意:
__proto__
是一个 🔺只读属性🔺 (前后两个杠)Chrome 中 [[prototype]] 和 __proto__
意义相同 用来表示当前实例对象指向哪个原型对象prototype __proto__
对象原型 里面也有一个 constructor属性 ,指向 创建 该实例对象 的 构造函数 ⚠🔺🔺 注意: (混淆点)
每个 构造函数 都有 prototype(原型对象) 每个 prototype(原型对象) 都有 constructor ,指向 该原型对象 的 构造函数 每个 对象 都有 __proto__
(对象原型) (属性),指向 构造函数 的 原型对象 每个 对象原型 都有 constructor
属性,指向 创建 该实例 的 构造函数 对象都会有一个属性 __proto__
指向构造函数的prototype原型对象,之所以对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有___proto__
🔺🔺⚠⚠总结:
1️⃣ prototype 是什么?哪里来的
2️⃣ constructor属性 在哪里?作用是啥?
prototype原型 和 对象原型 __proto__
里面 都有 都 ➡ 创建 原型 / 实例对象 的 构造函数 3️⃣ __proto__
属性在哪里?指向谁?
在 实例对象 里面 ➡ 原型对象 prototype
11.4 原型继承
JS中大多是 借助 原型对象 实现 继承 的特性
父构造函数(父类) 子构造函数(子类) 子类的原型 = new 父类 使用构造函数实现继承:
类:创建一类对象的模板 原型链继承:利用原型链的关系,实现继承的效果
在ES6之前,没有继承的语法,可以使用call和原型链来完成继承的效果,子构造函数继承父构造函数 1、子构造函数 创建的实例 拥有 父构造函数 创建的实例 相同 属性结构(call借用父构造函数的代码,修改其中this指向为子构造函数的实例) 2、子构造函数 创建的实例 可以调用 父构造函数 原型对象 的 公共成员(把 子构造函数 的原型对象 的 原型对象 变成,父构造函数的原型对象)
11.5 ❗❗ 原型链
基于 原型对象 的 继承 使得 不同构造函数 的 原型对象 联系在一起,并且这种 关联关系 是一种 链状结构 ,我们将 原型对象 的 链状结构关系 称为 原型链
从实例出发,以原型对象为连接,形成的一个链式的结构 由原型对象的关系相连,形成的链式结构
实例成员调用的时候,优先调用自身的成员,如果自身没有,继续调用原型对象的成员,如果原型对象也没有,就调用原型对象的原型对象的成员 原型链的作用: 实例调用成员的查找顺序原型链主要指的是__proto__
🔺🔺⚠⚠总结:
只要是 对象 就有 __proto__
,指向 原型对象 只要是 原型对象 里面就有 constructor,指向 创建 该原型对象 的 构造函数 实例对象 和 原型对象本身 可以 访问 定义在原型身上的方法或属性
构造函数不行(中间隔着prototype) 构造函数访问不了原型身上的属性或方法,因为中间隔着 prototype 实例对象可以访问原型对象的原型对象身上的属性和方法,中间虽然隔着东西,但能直接访问,因为这是规则 原型链-查找规则
当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性 如果没有就查找它的原型(也就是__proto__
指向的prototype原型对象) 如果还没有就查找原型对象的原型(Object的原型对象) 依此类推一直找到Object为止(如果 Object.prototype
也没有得到的就是 ) __proto__
对象原型的意义在于为对象成员查找机制提供一个方向,或者说一条路线可以使用 instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上
11.6 instanceof
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
简单理解:
判断 当前构造函数的原型对象 是否出现在 实例的原型链上 检测 实例对象 是否 由 该构造函数 创建 出来的 描述:
instanceof
运算符用来检测 constructor.prototype
是否存在于参数 object
的原型链上 语法: object instanceof constructor
参数:
object
- 实例对象constructor
- 构造函数 代码展示:
function C ( ) { }
function D ( ) { }
var o = new C ( ) ;
o instanceof C ;
o instanceof D ;
o instanceof Object ;
C . prototype instanceof Object
C . prototype = { } ;
var o2 = new C ( ) ;
o2 instanceof C ;
o instanceof C ;
D . prototype = new C ( ) ;
var o3 = new D ( ) ;
o3 instanceof D ;
o3 instanceof C ;