Labs 导读
Web应用作为互联网内容的重要组成部分。随着Web2.0概念的蓬勃发展和包括WebAssembly、WebGL2.0等技术的演进,Web应用在很多场景下已经具备和原生相媲美的性能,近些年Web应用又有了哪些新的进展,Safari和Webkit 中有一些怎样有趣又好玩的功能呢,蓝狮注册登陆让我们一起来探索一下吧~
Tips:
本文主要面向使用JavaScript、WebAssembly、WebGL的Web 应用开发者。
本文提及部分特性或api在Safari14.2以下版本中可能暂未支持,可以使用Safari Technology Preview – 14.2[1]调试。
具体API的使用和支持情况可以参考 MDN Web Docs[2],但文档更新可能会有延迟。
本文知识目录:
1JavaScript语法增强
1.1 使用#修饰类的属性、静态变量、方法,保证它们仅在类的内部可见
需要注意的是增加#后,#已经是名称的一部分,比如#_startTime才是一个完整的变量名。
//class with private variable and function
class 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; //SyntaxError
counter.#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()判断对象是否被GC
weakStopwatch.deref()?.click();
}
}
但是由于FinalizationRegistry的运行依赖于GC,GC的运行又依赖于event loop机制,所以存在一些不确定性。比如回调时机可能和你预期的不一致,所以在使用之前要评估下你的场景是否适用这几个方法,避免掉到坑里。
1.3 采用await方式import Module
await这个概念出现在了很多的编程语言中,它的最主要特征就是简化异步调用,让代码的可读性极大增强。原来await只能在async函数中使用,但是现在也可以在import module的时候使用,让module之间的依赖管理变得更加简单,比如像下面这样:
0 Comments