导图社区 js进阶知识点总结
js进阶知识点总结的思维导图,介绍了声明提升、正则表达式、基础、函数、ES6、ES5等方面,收藏下图参考学习吧!
编辑于2022-05-09 21:55:44JSCORE
声明提升
变量和函数的声明, 会在JS代码编译阶段被放入内存中
简单说: JS代码会执行两次
首先
把变量和函数的声明读取到所在作用域的顶部
然后
执行剩余的代码
函数声明
提升整个函数到顶部, 提升优先级比变量高
变量声明
仅提升声明部分到顶部, 不提升赋值操作
var
提升后的默认值为undefined
赋值前可以使用
const/let
提升后的默认值为undefined
也有人认为不提升, 理由如下
在声明函数执行之前, 变量处于暂存死区状态
暂存死区: 作用域中知道这些变量的存在, 但是在声明函数执行之前无法使用
基础
宿主环境
JS本身具有少量的基础API, 例如 Math, Date, console 等
JS运行的环境称为宿主环境, 提供额外的专属API
Node.js
提供了服务器相关的功能API
浏览器
提供了操作浏览器相关的API
window对象
浏览器中具有一个window对象, 其中包含了所有全局的API
对象
引用类型
一个变量中存储对象类型, 实际存储的是对象的地址, 这个地址指向对象实际存储在堆内存中的位置
对象类型的变量在赋值给其他变量时, 是对象的地址赋值给目标变量
构造函数
可以快速构建固定结构对象的函数
new运算符
搭配函数使用, 可以隐式完成一些操作, 返回一个新的对象
隐式操作
let this = {}
this.__proto__ = 函数.prototype
return this
原型链机制
对象使用一个属性时, 优先从自身查找. 如果自身没有, 则到其__proto__属性中查找
原型prototype
构造函数的prototype属性中, 可以保存对象使用的各种方法
在构造函数中, 会自动把 原型prototype 赋值给 生成对象的 __proto__ 属性
优点: 同一个构造函数生成的多个对象, 其 __proto__ 指向的都是 构造函数的 prototype, 实现了对象方法的复用
数据类型
number, string, boolean, undefined, null
对象
symbol
为对象属性添加不重复的唯一标识
bigint
大整型数字
ES6新增
var
全局变量污染
var在全局区声明变量时, 变量会存储在window中, 污染全局区
作用域
全局作用域
window
包含全局API
var在全局声明的变量存储在这里
script
利用 let/const 在全局区中声明的变量存储在这里
函数作用域
函数体中
local
块级作用域
利用 {} 配合 let / const 关键词, 形成的作用域
block
函数
arguments
一个函数体中的隐藏属性, 其中保存了函数的所有参数
是一个伪数组类型, 其原型非数组类型, 不具备数组的相关方法
函数重载
通过判断函数的参数个数/类型不同, 在函数体中执行不同的逻辑代码
this
this指向运行时所在对象
闭包
函数声明时, 会保存其所在的词法环境
详细说明
函数声明时, 为了保障在后期调用时能够正常执行, 会查看函数体中使用了哪些变量, 然后根据作用域链的就近原则, 找到这些变量所在的作用域, 把他们保存在自己的 scopes 变量中, 这些被保存的作用域中, 属于函数作用域的称为 闭包(closure)
函数柯里化
把一个多参数函数 改为单参数函数的方式
add(11)(22)(33)
function add(a){ return function (b){ return function (c){ return a+b+c } } }
ES5
ECMAScript 第五个版本, 发布与2009年
严格模式
在脚本顶部书写 'use strict' 字符串, 则后续代码都会运行在严格模式下
变量必须声明后才能使用
防止变量名书写错误导致错误的全局变量生成, 导致污染
函数的this如果指向window, 现在变为 undefined
防止构造函数忘记写new, 导致this指向window造成全局变量污染
取消静默失败
以前不报错的失败, 现在会爆红
取消函数的callee
arguments 的 callee 属性代表当前函数, 在匿名函数递归的场景中使用较多, 但是消耗资源多
现在推荐使用 命名函数递归 代替 匿名函数递归
函数
bind
为函数绑定执行所在的对象和相关参数, 返回一个新的函数, 等待后续执行
场景: 定时器 等延时执行的场景
call
立即触发函数, 把函数放在指定对象中执行, 并传入其他参数
场景: 执行时临时替换函数的this
apply
立即触发函数, 把函数放在指定对象中执行, 其他参数用数组传入
场景: 把函数的参数改为数组方式传入
数组的高阶函数
every
每个元素都符合条件
some
至少存在一个符合条件的元素
map
映射, 把数组的每个元素进行处理后, 返回值组成新的数组
filter
把符合条件的元素过滤出来, 形成新的数组
forEach
单纯的数组遍历
reduce
合并数组的每个元素, 最终得到一个值
对象方法
Object.defineProperty
修改旧属性, 配置详细设置
用字面量方式声明的属性, 默认的所有配置都是真
添加新属性, 配置详细设置
所有配置默认都是假
配置:
writable
可写
enumerable
可遍历
configurable
可重新配置
value
默认值
get
计算属性使用
读取属性时触发
set
赋值监听时使用
向属性赋值时触发
Object.defineProperties(对象, {属性名: 配置项})
配置多个属性
Object.preventExtensions
不允许新增属性
Object.seal
不允许增删属性
Object.freeze
不允许增删改属性
ES6
ECMAScript 第六个版本, 发布于2015年. 是JS提供特性最多的版本, 升级最大的版本
非常好的参考文档 https://es6.ruanyifeng.com/#docs
let
块级作用域
同一作用域中, 不允许重复声明
在全局作用域中声明, 变量会存储在脚本区, 而非全局window中, 所以不会造成全局变量污染
推荐用let 代替 var
const
块级作用域
在全局作用域中声明, 变量会存储在脚本区, 而非全局window中, 所以不会造成全局变量污染
同一作用域中, 不允许重复声明
声明时必须赋值, 后续不允许重新赋值
在没有重新赋值的场景中, 推荐用const 代替 let
数组的展开
... 运算符, 可以把数组展开
常用于把数组展开成函数参数, 代替 函数的apply 方法的场景
Math.max(...[11,22,33])
合并数组
[...数组1, ...数组2]
对象的展开
... 运算符, 可以把对象类型展开
合并对象
{...对象1, ...对象2}
剩余参数
function 函数(a, ...args)
args 非固定名称, 可以随意书写
示例函数, 剩余的参数都会存储在 args 这个数组类型的变量里
参数默认值
function 函数(参数=值)
数组解构
let [a,,c] = [11, 22, 33]
a = 11 c = 33
对象解构
let {name, age} = {name: 11, age:22}
name = 11 age = 22
别名写法
let {name: gname, age} = {name: 11, age: 22}
gname = 11 age = 22
模板字符串
``
配合 ${} 关键词, 可以在 模板字符串中书写JS代码
场景
在DOM操作中, 常用于拼接 HTML 模板代码
箭头函数
匿名函数的简化写法
()=>{}
语法糖1
当参数仅有一个时, 简化()
name => {}
语法糖2
方法体只有一行代码时, 简化 {return }
()=> {return xxx}
()=>xxx
注意
如果 返回值是对象类型, 则必须用()包裹, 来防止{}的歧义
()=> ({xx: xxx})
this
本身没有this, 使用声明时所在作用域中的this
不能做构造函数使用
搭配new使用会报错
没有 bind, call, apply 这些方法
对象方法
Object.keys
获取对象所有可遍历的直属属性
Object.setPrototypeOf
替换对象类型的原型
Object.create
创建对象类型时, 指定其原型和属性
for of
快速遍历数组类型, 得到其中的值
for (let value of arr){}
Promise
一种实现异步操作的方式
旧方式: 回调函数
有造成回调地狱的风险
Promise利用链式语法来防止回调地狱的发生
基础语法
new Promise((resolve, rejected)=>{ resolve({}) reject({}) }).then(res=>{}).catch(err=>{})
resolve会触发 then函数, 其参数会传递给 res
reject 会触发 catch 函数, 其参数会传递给 err
resolve 和 reject 二选一, 只能触发其中一个, 触发之后另一个无法触发
三种状态
pending
准备就绪, 初始
fulfilled
resolve 已解决
rejected
reject 被拒绝, 失败
class
面向对象三大特征
封装
用{} 把代码括起来, 后续通过名字进行调用
继承
原型链效果: 自己没有的属性, 去__proto__中查找
多态
继承同一个构造函数后, 可以得到更多具有个人特色的构造函数, 这些构造函数重写父的属性, 可以具有多种状态效果
JS提供了独特的 构造函数方式语法
function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return '(' + this.x + ', ' + this.y + ')'; }; var p = new Point(1, 2);
这种语法与传统的面向对象语言, 例如 C++ JAVA PHP Python 等等.. 差异非常大, 很容易让这些程序员感觉困惑
ES6提供了更接近传统语言的写法, 本质上是一个语法糖, 让传统程序员更容易学习和接受
class 类名 extends 父类 { static 静态属性 static 静态方法(){} constructor(a, b){ this.a = a this.b = b } 对象方法(){ super.对象方法() } }
extends是继承的关键词
相当于 类.prototype.__proto__ = 父类.prototype
static
静态关键词, 相当于 类.属性名 = 值
constructor
构造方法
super
代表父类的关键词
this
代表当前对象的关键词
正则表达式
RegExp
一套通用的字符串模糊匹配方案
元字符
一套固定的字符集, 代表不同的含义
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
声明方式有两种
/正则表达式/修饰符
字面量
new RegExp(正则字符串, 修饰符)
构造
修饰符
i
忽略大小写
g
全局匹配
字符串的正则方法
match
匹配
字符串.match(正则对象)
replace
替换
字符串.replace(正则对象, 要替换成)
捕获组
()称为捕获组
$n: 使用第n个捕捉组捕捉的值
正则的方法
test
格式验证
正则对象.test(字符串)
使用 ^ 代表字符串开头 使用 $ 代表字符串结尾