Skip to content
On this page

WX20220116-001152@2x

思考时刻

写文章时,把最精彩的部分写在前面,因为人的精力是有限的,需要先把最好的内容呈现出来,才能勾起继续看下去的欲望,就像抖音的视频一样,前几秒展示视频最精彩部分的点赞一般都会多些

通过 effie 了解到 LXGW WenKai / 霞鹜文楷 这个中文字体,很漂亮,推荐 👍

LXGW WenKai / 霞鹜文楷

【TED 演讲】想学会一个语言?就像玩电子游戏般地去说出来 (使用有趣的故事勾起继续看下去的欲望,演讲真的是一门学问)

  1. 现在的英语是一种为了能得到结果的工具,在英语对话中,只有 4%是英语母语者与英语母语者对话的
  2. 你在说英语时,不应该去评判自己的对错或好坏,而应该关注于是否能达成让对方理解你给他的结果

现在的 AI 已经很厉害了,在翻译、语音识别、图像识别上已经有很多应用了,可以了解下简单的基本原理

精彩看点

  1. colors.js 与 faker.js 遭开源作者故意破坏
  2. node util 模块好用的工具函数
  3. null 和 undefined 区别

阅读文章

下载量和 Vue 一样大的开源软件被作者恶意破坏,数千款应用受到牵连

内容

colors.js 与 faker.js 遭开源作者故意破坏,他认为:不会再“无偿工作”来支持那些商业巨头,要么选择项目分叉,要么以每年“六位数”的薪酬补偿开源开发人员。

faker.js 的 README 也改为“Aaron Swartz 到底经历了什么?”的字样。

Swartz 是一位杰出的开发人员,他帮助建立了 Creative Commons、RSS 和 Reddit。他的贡献对几乎所有的 Web 开发人员都产生了深远的影响。2013 年,年仅 26 岁的 Swartz 在一场法律纠纷中自杀身亡。

为了让所有人都能免费访问信息,这位黑客主义者从麻省理工学院的校园网络 JSTOR 数据库中下载到数百万篇期刊文章。据称,他采用的方法是反复轮换自己的 IP 与 MAC 地址以绕过校方和 JSTOR 设置的技术屏蔽方案。但此番举动也导致 Swartz 面对违反《计算机欺诈与滥用法》的指控,一旦罪名成立,他最高可能被判处 35 年监禁。

开源作者的 GitHub 账号也被停止使用(GitHub 也有可能禁用你的账号,所以最好还是自己备份下吧)

Marak 的此次过激行为发生在不久前影响巨大的 Log4j 漏洞事件之后。作为一套重量级开源库,Log4j 在不同企业及商业实体开发的各类 Java 应用程序当中都有广泛使用。而 Log4shell 漏洞的曝光引发越来越多 CVE,不少开源维护者不得不在休假期间无偿帮助修复这些免费项目。

思考

对酬劳的抱怨可以理解,但故意破坏的行为确实过激(我一直以为,能写出这样库的开源作者都不会为钱发愁呢 😐)

下载量对比

Node.js 内置的 util 模块究竟有多好用?

内容

JS 自带的类型判断令人头疼,util/types 可以帮你判断类型

js
const types = require('util/types');

types.isDate(new Date()); // true
types.isPromise(new Promise(() => {})); // true
types.isArrayBuffer(new ArrayBuffer(16)); // true

深比较是否完全相等 isDeepStrictEqual

js
const util = require('util');

const val1 = { name: 'shenfq', x: 1 };
const val2 = { x: 1, name: 'shenfq' };

console.log('val1 === val2', val1 === val2); // false
console.log('isDeepStrictEqual', util.isDeepStrictEqual(val1, val2)); // true

早期的 Node API 都是 Error First 风格的,现在大多是基于 promise 编程,那么如何将 Error First 风格的 API 转为 Promise API?

使用 promisify

js
const fs = require('fs');
const util = require('util');

const readFile = util.promisify(fs.readFile);
readFile('./a.ts', { encoding: 'utf-8' })
    .then(text => console.log(text))
    .catch(error => console.error(error));

顺便说一句:callbackify 可以将 Promise 风格转为 Error First 风格

Node 10 版本引入了 promises 属性,使用起来更简便

js
const fs = require('fs').promises;
fs.readFile('./a.ts', { encoding: 'utf-8' })
    .then(text => console.log(text))
    .catch(error => console.error(error));

util.debug 能实现类似 debug 包的效果,输出信息便于调试

util.format 可以格式化输出字符串

util.inspect 可以控制输出的对象

思考

Error First 风格转换 Promise 风格很有用,方便了 async 模式开发(在知道 promisify 之前,我也想写一个自己的 promisify 来着,但后来感觉太难就放弃了 😂,可以了解下源码是如何实现的)

能否把这个 util 弄到浏览器上呢?

深入探究:null 和 undefined 究竟有何区别?

内容

undefined:这个变量未定义,null:变量定义了,但表示的值为空(一般表示对象的初始值,类似字符串的初始值为空字符串)

之后演示了几种不同的展现形式,并解释其原因

js
typeof null; // 'object' 因为历史原因
typeof undefined; // 'undefined'

Object.prototype.toString.call(null); // '[object Null]'
// Object.prototype.toString() 是 Object 的原型方法
// 调用该方法,默认返回当前对象的内部属性 [[Class]],其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
Object.prototype.toString.call(undefined); // '[object Undefined]'

null == undefined; // true
// 并不是因为会隐式转换,而是因为ECMA 在 11.9.3 章节中表明了:
// If x is null and y is undefined, return true.
// If x is undefined and y is null, return true.

let a = undefined + 1; // NaN
let b = null + 1; // 1
Number(undefined); // NaN
Number(null); // 0

JSON.stringify({ a: undefined }); // '{}'
JSON.stringify({ b: null }); // '{b: null}'
JSON.stringify({ a: undefined, b: null }); // '{b: null}'
// JSON 会将 undefined 对应的 key 删除,这是 JSON 自身的转换原则。

function test(n) {
    let undefined = 'test';
    return n === undefined;
}
test(); // false
test(undefined); // false
test('test'); // ture
let undefined = 'test'; // Uncaught SyntaxError: Identifier 'undefined' has already been declared
// null 是关键字,而 undefined 是一个全局变量,可以使用局部变量覆盖,但一定不要这样做
// 如果你想要觉得真实的 undefined,可以使用 void 0 获取,因为 void 加任何表达式,都会返回 undefined

到底使用 undefined 还是 null,大家都有自己的准则,但团队内尽量保持统一

思考

局部 undefined 还可以重新赋值,这个真没想到,所以还是 void 0 保险一些

通过 Chrome Devtools 的 Memory 工具证明 string 的内存分配方式

内容

给出一个简单且有效的示例,使用 Memory 中的 Allocation instrumentation on timeline 模式,通过不同时间申请 string 来校验 string 的内存分配方式。

思考

"guang"@756367 at 后面表示的为内存地址

虽然看见了内存地址位置,但怎么证明这块内存地址是 栈、堆 还是 常量池 呢?🤔

2022-01-07 ~ 2022-01-13(第 5 期)