FrankKai

Results 350 comments of FrankKai

### REPL repl模块的全称是Read-Eval-Print-Loop(REPL),既可以独立使用也可以被其他应用程序使用。 ```js const repl = require('repl'); ``` #### 设计初衷 - repl导出repl.REPLServer类,运行时repl.REPLServer接收用户输入的内容,根据用户自定义函数执行输入,然后输出结果。 - 输入输出可能来自stdin和stdout,或者可以连接到任何Node.js流。 - repl.REPLServer支持`自动输入、简化Emacs 式行编辑、多行输入、ANSI式输出、保存当前REPL会话状态、错误恢复,以及定制执行函数` #### 命令和特殊键 下面的命令被REPL实例支持: - .break-输入多行表达式以后,可以键入.break命令(键入 `-C`)中止输入或者表达式的处理。 - .clear-重置REPL的context为空对象,清除所有已经输入的多行表达式,类似`-U、-K`。 - .exit-关闭I/O stream,退出REPL。 -...

### require.cache 在写vscode插件的过程中,发现通过require获取到的文件是旧的,不能获取到最新的。 原因是cjs的require有缓存机制,因此可以通过下面这种方式去获取: ```js // 避免require缓存 delete require.cache["/client/static/locales/zh/translation.json"]; const data = require("/client/static/locales/zh/translation.json"); ``` > Modules are cached in this object when they are required. By deleting a key value...

### 初识WeakMap - WeakMap对象是一组键值对的集合,其中key是弱引用的 - WeakMap的**key必须是对象类型**,value可以是任意类型 #### WeakMap的key为什么是弱引用的? 弱引用的意义:如果是作为key的对象没有**任何地方引用它**的话,垃圾收集器(GC)会将其标记为目标并且进行**垃圾回收**。 #### WeakMap的key和value可以是哪些类型 key:必须是任意object类型(对象、数组、Map、WeakMap等等) value:any(任意类型,所以也包括undefined,null) #### WeakMap与Map最大的不同 WeakMap的key是不可枚举的,而Map是可枚举的。 不可枚举就意味着获取不到WeakMap的key列表。 设计为不可枚举的原因是因为:如果枚举WeakMap的key,那就需要依赖垃圾回收器(GC)的状态,从而引入不确定性。

### 新增WeakMap类型是为什么? map API在js中可以通过共享4个API(get,set,has,delete)的两个数组来实现:一个存储key,一个存储value。在这个map上设置元素同步推入一个key和一个value到数组尾部。作为结果,key和value的索引会和两个数组绑定起来。从map获取一个值得话,会遍历所有key去找到一个匹配的,然后使用这个匹配到的index从values数组中查询到对应的值。 这样实现的话会有2个主要的弊端: 1. 首先是set和search的时间复杂度是O(n),n是map中key数组的数量,因为都需要遍历列表去查找到需要的值 2. 其次是会造成**内存泄漏**,因为数组需要**无期限地去确保每个key和每个value的引用**。这些引用会导致阻止key被垃圾回收掉,即使这个对象没有任何地方再引用到了,key对应的value也同样会被阻止垃圾回收。 相比之下,原生的`WeakMap`会保持对key的“弱”引用。原生的`WeakMap`不会阻止垃圾回收,最终会移除对key对象的引用。“弱”引用同样可以让value很好地垃圾回收。WeakMap特别适用于key映射的信息只有不被垃圾回收时才有价值的场景,换句话说就是**WeakMap适用于动态垃圾回收key的场景。** 因为引用是弱的,所以WeakMap的键是不能枚举的。没有方法去获取key的列表。如果枚举WeakMap的key,那就需要依赖垃圾回收器(GC)的状态,从而引入不确定性。如果必须要有key的话,应该去使用`Map`。

### WeakMap的基本概念 #### 语法 ```js new WeakMap() new WeakMap(iterable) ``` 其中iterable是数组或者任意可以迭代的对象,需要拥有key-value对(一般是一个二维数组)。null会被当做undefined。 ##### iterable为二维数组 ```js const iterable = [ [{foo:1}, 1], [[1,2,3], 2], [window, 3] ] const iwm = new WeakMap(iterable)...

### WeakMap最简使用方式 ```js const wm1 = new WeakMap(), wm2 = new WeakMap(), wm3 = new WeakMap(); const o1 = {}, o2 = function() {}, o3 = window; wm1.set(o1, 37); wm1.set(o2,...

### WeakMap存储私有数据 实例和原型链上的数据和方法是公开的,所以可以通过WeakMap类型的私有变量去隐藏实现细节。 ```js const privates = new WeakMap(); function Public() { const me = { // Private data goes here }; privates.set(this, me); } Public.prototype.method = function () {...

### 拥有clear方式的WeakMap类 ```js class ClearableWeakMap { constructor(init) { this._wm = new WeakMap(init); } clear() { this._wm = new WeakMap(); } delete(k) { return this._wm.delete(k); } get(k) { return this._wm.get(k); }...

### WeakMap式自动垃圾回收缓存函数 [实现缓存函数的方式](https://github.com/FrankKai/FrankKai.github.io/issues/223)有很多种,比如单次缓存,Map式全量缓存,LRU最近最少缓存等等。 那么为什么还需要WeakMap式的缓存函数呢?这是因为入参为对象类型的缓存且方便浏览器垃圾回收。 #### 缓存函数实现 ```js function memoizeWeakMap(fn) { const wm = new WeakMap(); return function (arg) { if (wm.has(arg)) { return wm.get(arg); } const cachedArg = arg; const...

参考资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Keyed_collections#weakmap_object https://fitzgeraldnick.com/2014/01/13/hiding-implementation-details-with-e6-weakmaps.html https://whatthefuck.is/memoization https://github.com/reactjs/react-basic