ES 新特性与 TypeScript、JS 性能优化
ES2015
1、Proxy
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)
使用:
const person = {}
cont personProxy = new Proxy(person, {
    get(target, property) {
        return property in target ? target[property] : 'default'
    },
    set() {}
})
2、Proxy对比defineProperty
Proxy相对于defineProperty更加强大,例如:
- proxy监听全对象,而defineProperty监听具体属性,需要指定
 - defineProperty无法监听到属性新增和删除,而proxy可以
 - defineProperty无法监听数组的变化
 - proxy以非侵入式方式监听,而defineProperty不是
 
3、Reflect
Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。Reflect不是一个函数对象,因此它是不可构造的。
- 提供统一的对象操作Api
 - 不能通过new,是静态方法类
 - 具有13个方法(原本14个,淘汰一个)
 
Reflect.apply(target, thisArgument, argumentsList) // 对一个函数进行调用操作,同时可以传入一个数组作为调用参数。和 Function.prototype.apply() 功能类似。
Reflect.construct(target, argumentsList[, newTarget]) //对构造函数进行 new 操作,相当于执行 new target(...args)。
Reflect.defineProperty(target, propertyKey, attributes) //和 Object.defineProperty() 类似。如果设置成功就会返回 true
Reflect.deleteProperty(target, propertyKey) // 作为函数的delete操作符,相当于执行 delete target[name]。
Reflect.get(target, propertyKey[, receiver]) // 获取对象身上某个属性的值,类似于 target[name]。
Reflect.getOwnPropertyDescriptor(target, propertyKey) // 类似于 Object.getOwnPropertyDescriptor()。如果对象中存在该属性,则返回对应的属性描述符,  否则返回 undefined.
Reflect.getPrototypeOf(target) // 类似于 Object.getPrototypeOf()。
Reflect.has(target, propertyKey) // 判断一个对象是否存在某个属性,和 in 运算符 的功能完全相同。
Reflect.isExtensible(target) // 类似于 Object.isExtensible().
Reflect.ownKeys(target) // 返回一个包含所有自身属性(不包含继承属性)的数组。(类似于 Object.keys(), 但不会受enumerable影响).
Reflect.preventExtensions(target) // 类似于 Object.preventExtensions()。返回一个Boolean。
Reflect.set(target, propertyKey, value[, receiver]) // 将值分配给属性的函数。返回一个Boolean,如果更新成功,则返回true。
Reflect.setPrototypeOf(target, prototype) // 设置对象原型的函数. 返回一个 Boolean, 如果更新成功,则返回true。
4、Symbol(符号)
- Symbol是新增的一种原数数据类型
 - 主要作用是为对象添加一个独一无二的标识符(可以理解为key)
 - 用Symbol模拟实现对象私有成员,避免、解决冲突
 - 数据类型:number、string、function、bigInt、symbol、boolean、undefined、object
 - 特殊类型:null,
JS 存在的一个悠久 Bug。在 JS 的最初版本中使用的是 32 位系统,为了性能考虑使用低位存储变量的类型信息,000 开头代表是对象然而 null 表示为全零,所以将它错误的判断为 object 
5、类的继承 extends
- 
在之前实现继承是通过原型的方式实现,现在可以通过class的extend可实现,内部实现上还是函数
 - 
由于class本质还是一个function 因此它就会拥有一个prototype属性,当new一个class时,会把class的porototype属性赋值给这个新对象的 proto属性
 - 
prototype是函数的一个属性,它是一个指针。对于构造函数来说,prototype是作为构造函数的属性。prototype也可以是一个对象,prototype是对象实例的原型对象。所以prototype即是属性,又是对象。在new一个对象时,可以理解为一个对象没有ptototype属性,所以把ptototype给一个对象的 proto
 
6、迭代器模式
- 提供统一的可迭代接口
 - 语法层面上实现了此种模式
 
7、生成器
- 在方法前增加一个*号,则代表一个生成器函数
 - 执行成功后返回的是一个对象
 - 需要通过next方法进行继续执行
 - 内部通过yield暂停
 - 其次yield后的值会作为本次next的结果返回
 - 同时会返回一个done的状态
 - 应用场景:发号器
 
8、es2016
- includes方法:检测是否存在,且兼容NaN
 - 指数运算符: **,如 2 ** 10
 
9、es2017
- object.values方法
 - object.entry方法,key、valye数组的形式拿到对象的内容
 - padStart,padEnd,如数字前补0
 
Typescript
概述
- ts是基于js之上的编程语言,解决js类型系统不足之处。
 - 通过ts可提高代码的可靠程度
 - ts是js的一个超集
 - js是动态类型,ts是静态类型
 - ts基于js添加了不少特性
 
ts作用域问题
- 变量默认在全局作用域,不允许重复
 - 默认使用export {} 变成模块导出
 
ts类型
- Object 类型:函数、数组、对象
 - Array 类型:Array, number[]
 - 元祖类型:tuple types,可以理解为明确的类型、明确的长度的数据类型
 - 枚举类型:enum,数字的是自动增加,字符串必须给定值,最终会变成双向的键值对
 - 函数类型:
 
    函数声明
        1、形参类型限制
        2、返回值类型
    函数表达式
        箭头函数式标明
- 任意类型:接受任意类型:any,属于动态类型
 - 隐式类型推断:未声明类型,则会进行自动类型推断
 - 类型断言:无法推断时,as关键词,尖括号,尖括号会和jsx冲突,建议使用as
 
接口
- 一种约定,一种规范
 - interface进行定义 接口
 - 形式为:key:类型
 - 约定对象的结构,且必须实现接口定义的内容
 - 可选成员:增加问好
 - 只读成员:增加readonly,赋值后就不许再改了
 - 任意成员:[x: types]: types
 
类
- 类用来描述一类具体事务的抽象特征
 - 类的访问修饰符:private,public(默认的),proteted(受保护的)
 - proteted:只允许在子类中使用
 - private:只允许类的内部使用
 - 只读属性:readonly,需要跟在修饰符后面
 - 一个接口最好只限制一种能力,一个类可以实现多个接口,使用implements关键字,多个接口使用逗号分隔
 
性能优化
- 内存管理
 - 垃圾回收与常见的GC算法
 - V8引擎的垃圾回收
 - performance工具
 
内存管理
- 内存:由可读写单元组成,表示一片可操作性的空间
 - 管理:人为的去操作一片空间的申请、使用和释放
 - 内存管理:开发者主动申请空间、使用空间、释放空间
 - js并没有api可以直接开辟空间,而是使用变量声明、创建函数、创建类等方式,通过浏览器来开辟空间
 - 使用空间时注意,避免不当操作造成空间泄露
 
垃圾回收
- js中内存管理是自动的
 - 对象不再被引用时即是垃圾
 - 对象不能从根上访问到时是垃圾
 
可达对象
- 可以访问到的对象就是可达对象
 - 可达的标准就是从根出发是否能够被找到(从根上,到作用域链查找等)
 - 根:可以理解为全局变量对象
 
GC算法介绍
- GC:就是垃圾回收机制的简写
 - GC 可以找到内存中的垃圾、并释放和回收空间
 - GC 里的垃圾是什么?
 - 程序中不在需要使用的对象
 - 程序中不能再访问到的对象
 - GC 是一种机制,垃圾回收器完成具体的工作,而工作内容就是查找垃圾并释放和回收空间;算法就是工作时查找和回收所遵循的规则
 - 常用的算法:引用计数、标记清除、标记整理、分代回收
 
GC:引用计数
- 核心思想:设置引用数,判断当前引用数是否为0,当为0的时候进行回收
 - 实现原理:
 - 维护一个引用计数器,当有变量引用时,计数器加1,不再引用时计数器减1,当计数器为0时,GC回收,释放空间
 - 引用计数器:因为计数器存在,导致和其他机制有所区别
 
优缺点
- 当发现为0时,立即回收
 - 减少 程序卡顿时间
 - 因为时刻监测内存,当快满的时候就回收,因此内存不会慢
 - 但是因需要维护计数器的变化,时间开销会相比其他机制大
 - 同时,如果两个对象互相引用,因为互相不为0,因此无法删除
 
标记清除
- 核心思想:分两个阶段,第一个阶段将活动对象进行标记,第二个标记将未标记的清除掉,同时消除之前的标记
 - 从根查找,沿着作用域链只要能找到的,就为可达对象,否则为不可达,后续会被GC进行清除
 
优缺点
- 可以解决引用计数时无法解决的互相引用问题
 - 互相引用时,在作用域执行完毕后从根递归查找已无法可达,因此会被清除
 - 缺点1:因清除掉后空间地址不连续,造成空间浪费
 - 缺点2:碎片化,不会立即清除
 
标记整理
标记阶段和标记清除机制一直,不同点在于,在执行完毕第一阶段后,在执行第二阶段标记清除之前,会先进行一次空间整理,移动对象的位置,使可达的活动对象空间地址是连续的,之后再进行清除操作
- 
减少碎片化
 - 
不会立即回收垃圾对象
 
V8
- 
V8是一款主流的js执行引擎,chrome平台已在使用
 - 
V8 采用即时编译
 - 
内存设限
64为系统中 1.5g
32为系统中 800M
原因就是:当内存使用到1.5g的时候,使用增量标记的方式需要使用500毫秒。使用其他方式需要1s,从用户体验角度来说,设定此上线,且使用增量标记较合理
 
V8垃圾回收策略
- 
采用分代回收思想,分为新生代、老生代,针对不同对象采用不同算法
 - 
先划分,按照新生代、老生代的模式分代回收
 - 
其次进行空间复制
 - 
标记清除
 - 
标记整理
 - 
标记增量
 
新生代回收
- 
新生代空间被分为等分两部分
 - 
在64为系统中是32M单个
 - 
在32位系统中是16M单个
 - 
新生代指的是存活时间较短的对象
 
- 等分的两个空间划分为:使用空间为From,空间空间为To
 - 如果声明变量时,开辟空间则会在From空间中存储,为活动对象,此时To空间为空闲状态,未使用
 - 当From空间使用到一定比例时将会出发GC操作,顺序是先进行标记整理,然后将活动对象拷贝至TO空间。拷贝完毕后From区域被进行释放,TO编程了使用状态。进行了交换
 
- 1、一轮GC后还存活的新生代需要晋升。
 - 2、TO空间的使用率超过25%,将全部拷贝至老生代(因为From和To需要交换,保证空间足够)
 
老生代回收
- 老生代对象存储在老生代区域
 - 老生代的空间大小限制为:64位操作系统是1.4g,32位操作系统是700M
 - 老生代对象就是指存活时间较长的对象
 - 老生代的回收主要采用标记清除、标记整理、增量标记算法
 - 首先:使用标记清除完成垃圾回见的回收,速度较快
 - 标记整理需要根据条件触发:当新生代空间向老生代空间晋升,但空间无法满足时,会先进行比较整理进行空间优化,
 - 最后采用增量标记进行效率优化
 
- 新生代使用空间换时间
 - 老生代不适合复制算法,原因:大,时间长
 
V8执行流程
- scanner-扫描器,将纯文本的代码进行扫描。做词法分析,得到词法单元,最小的一个单元
 - parser-解析器,语法分析,将词法分析的数据进行转化为ast树
 - preparser,预解析,全量解析
 
示例
// 声明时未调用,因此会被认为是不被 执行的代码,运行预解析
function foo() {
    console.log('foo')
}
// 声明时未调用,因此会被认为是不被执行的嗲吗,进行预解析
function fn() {}
// 函数立即执行,只进行一次全量解析
(function bar() {
    
})()
// 执行foo 那么需要重新对foo函数进行全量解析,此时foo函数被解析了两次
foo()
- lgnition 是V8提供的一个解释器
 
- turBoFan 是编译器模块
 
函数防抖与节流
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
 - 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
 
- 提示下载完但解压或打开不了?
 
- 找不到素材资源介绍文章里的示例图片?
 
- 模板不会安装或需要功能定制以及二次开发?
 
                    
    
发表评论
还没有评论,快来抢沙发吧!