ECMAScript新特性,TypeScript语言,Javascript性能优化

ECMAScript新特性

TypeScript语言

作用
解决javascipt自有类型系统的问题,大大提高代码的可靠程度
强类型和弱类型
强类型不允许随意的隐式类型转换,而弱类型是允许的
静态类型和动态类型
静态类型:声明过后,它的类型不允许再修改
动态类型:在运行阶段才能明确变量类型,而且变量的类型可以随时改变
在这里插入图片描述
javascript则是弱类型、动态类型语言,缺失了类型系统的可靠性;没有编译环节,需求不多

Flow

TypeScript

作用

在这里插入图片描述
任何一种javascript运行环境都支持,功能更为强大,生态也更健全、更完善(Angular/vue.js3.0);前端领域的第二语言,适合长周期大项目;

缺点
一、语言本身多了很多概念(属于渐进式)
二、项目初期,TypeScript会增加一些成本
快速上手
yarn init --yes 初始化项目中的package.json,管理项目的依赖性
yarn add typescript --dev 做为项目的开发依赖来安装
yarn tsc 文件名 会生成一个js文件(ECMAScript3的语法)
如果使用yarn命令报错使用以下方法修改权限
window +x -> Windw.powerShell(管理员A) -> set-ExecutionPolicy RemoteSigned -> y -> get-ExecutionPolicy
配置文件
编译整个项目,编译之前创建一个typescript配置文件
yarn tsc --init 运行之后会生成一个tsconfig.json文件
原始类型
标准库就是内置对象所对应的声明
中文错误消息
yarn tsc --locale zh-CN
作用域问题
两种方法,第二种更常用
//方法一
// (function(){
//     const a=123
// })()
//方法二
const a=123
export {}
Object类型

export {} //确保跟其它示例没有成员冲突
const foo:object=function(){}//[]//{}
const obj:{foo:number,bar:string}={foo:123,bar:'string'}
数组类型

const arr1:Array<number>=[1,2,3]

const arr2:number[]=[1,2,3]

// -----------------------------
function sum(...args:number[]){
    // 判断是不是每个成员都是数字
    return args.reduce((prev,current)=>prev+current,0)
}
元组类型
明确元素数量,以及每个元素类型的数组
const tuple:[number,string]=[12,'zce']

// const age=tuple[0]
// const name=tuple[1]

const [age,name]=tuple
// ------------------------------
Object.entries({
    foo:123,
    bar:456
})
枚举类型

// const PostStatus={
//     Draft:0,
//     Unpublished:1,
//     Published:2
// }

const enum PostStatus{
    Draft=0,
    Unpublished=1,
    Published=2
}
// 如果不给定指定的值,默认会从0开始累加,如果给第一个属性一个固定值,后面会在这个基础上累加
const post={
    title:'Hello TypeScript',
    content:'TypeScript is a typed superset of JavaScript.',
    status:PostStatus.Draft//2//1//0
}
函数类型

function func1(a:number,b?:number,...rest:number[]):string{
    return 'func1'
}

// -----------------------------------------------
const func2:(a:number,b:number)=>string=function(a:number,b:number):string{
    return 'func2'
}
任意类型

function stringify(value:any){
    return JSON.stringify(value)
}

stringify('string')
stringify(100)
stringify(true)

let foo:any='string'
foo=100
foo.bar()
// any类型是不安全的
隐式类型推断

let age=10//number
// age='string'

let foo
foo=100
foo='string'
// 建议为每个变量添加明确的类型
类型断言
类型断言并不是类型转换,只是在编译过程的转换,而类型转换是代码在运行时的概念
// 假定这个nums来自一个明确的接口
const nums=[110,120,119,112]
const res=nums.find(i=>i>0)
// const square=res*res
const num1=res as number
const num2=<number>res//JSX下不能使用
接口
一种规范(契约),约束一个对象的结构
interface Post{
    title:string
    content:string
}

function printPost(post:Post){
    console.log(post.title);
    console.log(post.content);
}
printPost({
    title:'Hello TypeScript',
    content:'A javascript superset'
})
// 可选成员、只读成员、动态成员
interface Post{
    title:string
    content:string
    subtitle?:string//可选成员
    readonly summary:string//只读成员
}

const hello:Post={
    title:'Hello TypeScript',
    content:'A javascript superset',
    summary:'A javascript'
}

// ---------------------------------------
interface Cache{
    [prop:string]:string
}

const cache:Cache={}

cache.foo='value1'
cache.bar='value2'

描述一类具体事物的抽象特征,用来描述一类具体对象的抽象成员;
es6以前,函数+原型 模拟实现类
es6开始javascript 中有了专门的class
typescript 增强了class的相关语法
class Person{//在typescript中类的属性必须要有一个初始值,可以在等号后面赋值,也可以在构造函数中赋值
    name:string//='init name'
    age:number
    constructor(name:string,age:number){
        this.name=name
        this.age=age
    }
    sayHi(msg:string):void{
        console.log(`I am ${this.name},${msg}`);
        
    }
}
//类的访问修饰符
class Person{//在typescript中类的属性必须要有一个初始值,可以在等号后面赋值,也可以在构造函数中赋值
    public name:string//='init name'
    private age:number
    protected gender:boolean
    // protected readonly gender:boolean //只读属性
    constructor(name:string,age:number){
        this.name=name
        this.age=age
        this.gender=true
    }
    sayHi(msg:string):void{
        console.log(`I am ${this.name},${msg}`);
        console.log(this.age);
    }
}

class Student extends Person{
    constructor (name:string,age:number){
        super(name,age)
        console.log(this.gender);
    }
}

const tom=new Person('tom',18)
console.log(tom.name);
泛型
在声明的时候不去指定具体类型,在调用的时候指定它的类型
function createArray<T>(length:number,value:T):T[]{
    const arr=Array<T>(length).fill(value)
    return arr
}
const res=createArray<string>(3,'foo')

Javascript性能优化

javascript语言的优化

内存管理

  • 内存:由可读写单元组成,表示一片可操作空间
  • 管理:认为的去操作一片空间的申请、使用和释放
  • 内存管理:开发者主动申请空间、使用空间、释放空间
  • 管理流程:申请-使用-释放
//memory management
// 申请
let obj = {}
// 使用
obj.name = 'lg'
// 释放
obj = null

垃圾回收与常见GC算法

  • javascript中内存管理是自动的
  • 对象不再被引用时是垃圾
  • 对象不能从根本上访问到时是垃圾

javascript中的可达对象

  • 可以访问到的对象就是可达对象(引用、作用域链)
  • 可达的标准就是从根出发是否能够被找到
  • javascript 中的根就可以理解为是全局变量对象

GC定义与作用

  • GC就是垃圾回收机制的简写
  • GC可以找到内存中的垃圾、并释放和回收空间
  • 算法就是工作时查找和回收多遵循的规则
    1.程序中不再需要使用的对象
    2.程序中不能再访问到的对象
常见的GC算法

引用计数

  • 核心思想:设置引用数判断当前引用数是否为0

  • 引用计数器

  • 引用关系改变时修改引用数字

    引用计数算法优点
    发现垃圾时立即回收
    最大限度减少程序暂停
    引用计数算法缺点
    无法回收循环引用的对象
    :时间开销大

标记清除

  • 核心思想:分标记和清除两个阶段完成
  • 遍历所有对象找标记活动对象
  • 遍历所有对象清除没有标记对象
  • 回收相应的空间

  • 标记整理
  • 分代回收

v8引擎的垃圾回收

Performance工具

谷歌浏览器提供的性能工具

内存问题

内存问题的提现

  • 页面出现延迟加载或经常性暂停
  • 页面持续性出现糟糕的性能
  • 页面的性能随时间延长越来越差

界定内存问题的标准

  • 内存泄漏:内存使用持续升高
  • 内存膨胀:在多数设备上都存在性能问题
  • 频繁垃圾回收:通过内存变化图进行分析

监控内存的几种方式

  • 浏览器任务管理器
    Shift+Esc
  • TimeLine时序图记录
    F12 performance(性能) 录制
  • 堆快照查找分离DOM1
    F12 memory(内存) Take snapshot(获取快照) 搜索deta
  • 判断是否存在频繁的垃圾回收(GC)
    在这里插入图片描述

代码优化

如何精准测试Javascript性能

  • 本质上是采用大量的执行样本进行数学统计和分析
  • 使用基于Benchmark.js的链接: https://jsbench.me/完成
    使用流程
    • 使用github账号登录
    • 填写个人信息(非必填)
    • 填写详细的测试用例信息(title,slug)
    • 填写准备代码(DOM操作时经常使用)
    • 填写必要的setup和teardown代码
    • 填写代码测试片段

慎用全局变量

  • 全局变量定义在全局执行上下文,是所有作用域的顶端
  • 全局执行上下文一直存在于上下文执行栈,直到程序退出
  • 如果某个局部作用域出现了同名变量则会遮蔽或污染全局

缓存全局变量

  • 将无法避免的全局变量缓存到局部
    在这里插入图片描述

通过原型新增方法

在这里插入图片描述

避开闭包陷阱

  • 外部具有指向内部的引用

  • 在“外”部作用域访问“内”部作用域的数据
    在这里插入图片描述

    关于闭包

    • 闭包是一种强大的语法
    • 闭包使用不当很容易出现内存泄漏
    • 不要为了闭包而闭包

避免属性访问方法使用

javascript中的面向对象

  • JS不需属性的访问方法,所有属性都是外部可见的
  • 使用属性访问方法只会增加一层重定义,没有访问的控制力
    在这里插入图片描述

for循环优化

在这里插入图片描述
最优的循环方式
在这里插入图片描述

文档碎片化节点添加

节点的添加操作必然会有回流和重绘
在这里插入图片描述

克隆优化节点操作

在这里插入图片描述

直接量替换new Object

在这里插入图片描述

JSBench

jsperf已经不维护了
链接: https://jsbench.me/完成

堆栈中的JS执行

减少判断层级
减少作用域查找层级
在这里插入图片描述
减少数据读取次数
在这里插入图片描述


  1. 界面元素存活在DOM树上;垃圾对象时的DOM节点;分离状态的DOM节点 ↩︎

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值