最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • ES 新特性与 TypeScript、JS 性能优化

    正文概述 掘金(宝贝的班长)   2021-08-13   571

    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 是编译器模块

    函数防抖与节流


    起源地下载网 » ES 新特性与 TypeScript、JS 性能优化

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元