本文始于这样一道 JavaScript 题目。
var a;
if (true) {
a = 5;
function a() {}
a = 2;
console.log(a);
}
console.log(a);
在 JavaScript 中没有类的概念,因此它的对象与基于类的语言中的对象不同。
ECMA-262 把对象定义为:无序属性的集合,其属性可以包含基本值、对象或函数。
一直以来在编程中都是使用 class
、extends
关键字,而这实际上是 ES6 中添加的语法糖。在熟练使用语法糖的同时,有必要了解其背后的原生实现。
在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。
Babel、UglifyJS2、ESLint、Webpack、TypeScript 等我们熟知的工具都包含 AST 的应用,实现了强大的功能。本文主要记录学习、应用 AST 的过程,主要内容:1. 解读 react-hot-loader dev 环境下的 Babel 插件;2. 编写对应的 TypeScript transformer 尽可能实现相同的功能。
情景还原:有一个用 Promise 封装的异步操作,用于 JS 与客户端交互以获取数据,但当出现并发调用获取数据的时候发现只有其中的一次操作有回调,而剩余的调用就像丢失了一样、后续的步骤(then)也得不到执行。实际上有多种解决方式,这里考虑将这些并发的调用转化为串行执行来确保每次的调用接收到回调。虽然感觉这样做可能意义不是很大,但感觉颇有意思。
从零搭建一个简单的脚手架工具,像vue-cli
一样,一个命令就能变出一个完整结构的初始项目。流行的脚手架工具有很多实用的功能,这里要说的是最基本的一项:通过一个命令快速创建出初始项目。
使用 Promise 对 setTimeout 进行封装,从而支持链式的调用。
const delay = (func, millisec, options) => {
let timer = 0
let reject = null
const promise = new Promise((resolve, _reject) => {
reject = _reject
timer = setTimeout(() => {
resolve(func(options))
}, millisec)
})
return {
get promise() {
return promise
},
cancel() {
if (timer) {
clearTimeout(timer)
timer = 0
reject(new Error('timer is cancelled'))
reject = null
}
},
}
}
使用🌰:
const d = delay(({a, b}) => {
console.log(a, b)
return a + b
}, 2000, {a: 1, b: 3})
d.promise.then((result) => {
console.log('result', result)
}).catch((err) => {
console.log(err)
})
// cancel
// setTimeout(() => {
// d.cancel()
// }, 1000)