作者:毛小俊
单位:中国移动智慧家庭运营中心
Tips:
- 本文主要面向使用JAVAScript、WebAssembly、WebGL的Web 应用开发者 。
- 本文提及部分特性或API在Safari14.2以下版本中可能暂未支持,可以使用Safari Technology Preview - 14.2[1]调试 。
- 具体API的使用和支持情况可以参考 MDN Web Docs[2],但文档更新可能会有延迟 。
- 文末有示例代码链接 。
文章插图
1 JavaScript语法增强1.1 使用#修饰类的属性、静态变量、方法,保证它们仅在类的内部可见
需要注意的是增加#后,#已经是名称的一部分,比如#_startTime才是一个完整的变量名 。
//class with private variable and functionclass PrivateStopWatchWithOneButton {//使用#定义私有变量#_startTime = 0;//使用#定义私有静态变量static #stopWatchCount = 0;click(){if (!this.#_startTime) {this.#start();}else{this.#stop();}}//使用#定义私有方法#start() {PrivateStopWatchWithOneButton.#stopWatchCount++;this.#_startTime = Date.now();console.log('StopWatch started');}}function demo(){var counter = new StopWatchWithOneButton();counter.click();counter.#stopWatchCount = 0; //SyntaxErrorcounter.#start();//SyntaxError}
1.2 WeakRef一种新的弱引用方法Map和Set是JavaScript中常用的集合类型,为了实现更高效的垃圾回收,在部分情况下需要通过WeakMap和WeakSet实现对集合对象的弱引用,但是WeakMap和WeakSet没有Iterator接口,因而无法实现迭代的逻辑 。所以Apple今年给出了几个新的接口,比如通过WeakRef获得对象的弱引用,同时可以通过FinalizationRegistry得知弱引用的对象被垃圾回收的时机,然后在注册的回调中执行一些清理操作 。
其中关键的几个概念:
- WeakRef:允许您保留对另一个对象的弱引用,而不会阻止被弱引用对象被GC回收 。
- FinalizationRegistry:可以让你在对象被垃圾回收时请求一个回调 。
- deref:返回WeakRef实例的目标对象,如果目标对象已被垃圾收集,则返回undefined。
class StopWatchWithOneButton {_startTime = 0;click(){//...}//some detail implimentation...}const allStopWatches= new Map();var nextAvailableIdentifier = 1;function removeStopwatch(identifier){/*当map中引用的StopWatchWithOneButton对象由于某种原因(生命周期结束/手动销毁)被系统回收后,需要将当前的Map数据清理一下 。*/allStopWatches.delete(identifier);}//通过FinalizationRegistry新建一个注册表,同时注册关联的回调函数const finalizationRegistry = new FinalizationRegistry(removeStopwatch);function createStopwatch(){let identifier = nextAvailableIdentifier++;let stopwatch = new StopWatchWithOneButton();//WeakRef()获得stopwatch的弱引用allStopWatches.set(identifier, new WeakRef(stopwatch));/*将stopwatch注册到finalizationRegistry这个注册表中,当stopwatch被垃圾回收时,便会调用上面的removeStopwatch函数,实现allStopWatches这个map数据的清理 。*/finalizationRegistry.register(stopwatch, identifier);return stopwatch;}function clickAllStopwatches(){console.log('ready to click all buttons');for(let weakStopwatch in allStopWatches.values()){//迭代获取weakStopwatch,通过deref()判断对象是否被GCweakStopwatch.deref()?.click();}}
但是由于FinalizationRegistry的运行依赖于GC,GC的运行又依赖于event loop机制,所以存在一些不确定性 。比如回调时机可能和你预期的不一致,所以在使用之前要评估下你的场景是否适用这几个方法,避免掉到坑里 。1.3 采用await方式import Module
await这个概念出现在了很多的编程语言中,它的最主要特征就是简化异步调用,让代码的可读性极大增强 。原来await只能在async函数中使用,但是现在也可以在import module的时候使用,让module之间的依赖管理变得更加简单,比如像下面这样:
上述await方法的使用,有以下两个效果:
1??stopwatch = new StopWatchWithOneButton();会在import执行完成之后再执行 。
2??如果被import的stopwatchInModule.js中有异步任务执行,stopwatch = new StopWatchWithOneButton();会在异步任务执行完成后继续执行 。
需要注意的是,await用来import module的时候仅在module类型的script中有效,其他类型的script会直接报错 。
1.4 在worker中使用module
由于JavaScript采用的是单线程模型,Web worker则为JavaScript创造了多线程环境,主线程可以通过创建Worker在子线程中执行一些脚本,将一些计算密集型或者高延迟的任务放到后台运行,保证UI交互的流畅性 。而Module则可以实现动态import、对加载和执行实现优化、实现依赖管理 。所以在worker中使用Module可以更轻松的将一些heavy work转移到后台线程 。module现在可以应用于多种不同类型的worker中,比如:web worker、service worker和worklet 。
推荐阅读
- office怎么激活学生版 office怎么激活
- 混搭|和平精英:鹤鸣混搭抢先看!免费皮肤也能穿出高级感!
- AMD|华擎首次杀入显示器:支持AMD高级绝技
- 零基础能不能学Web前端开发? web是什么意思
- 生科医学|超1.6万例!世卫针对猴痘发布最高级别警报
- 斗篷|郑欣宜为爱瘦身有效果,黑色斗篷裙霸气高级,恋爱中的状态果然好
- 这些礼物小众又高级,建议收藏。 朋友过生日送什么礼物好
- 微软|苹果Safari被拒之门外:微软禁止WebKit内核浏览器上架商店
- 穿衣搭配|40岁后如何打造上班穿搭?分享4个实用技巧,轻松打造优雅高级感
- 有哪些高级的、含蓄的骂人的话?