Live Note

Remain optimistic

简单的 Queue 实现

数组实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class Queue {
constructor(size = 10) {
this.size = size // 队列最大长度
this.top = 0 // 首位置
this.bottom = -1 // 尾位置
this.elems = 0 // 成员个数
this.arr = [] // 队列
}

add(elem) {
if (this.elems == this.size) {
console.log("Queue is full")
return
}
if (this.bottom == this.size - 1) {
// 循环队列
this.bottom = -1
}
this.arr[++this.bottom] = elem
this.elems++
return true
}

out() {
if (this.elems == 0) {
console.log("Queue is empty")
return
}
let elem = this.arr[this.top]
this.arr[this.top] = null
this.top++
if (this.top == this.size) {
this.top = 0
}
this.elems--
return elem
}
}
var queue = new Queue()
queue.add(3)
queue.add(2)
console.log(queue.out())
console.log(queue.out())
console.log(queue.out())
Read more »

JavaScript 采用的是词法作用域(lexical scoping)

JavaScript 函数的作用域在函数定义的时候就确定了,所以实际使用的值与函数定义位置有关系。

1
2
3
4
5
6
7
8
9
10
11
12
let value = 1

function foo() {
console.log(value)
}

function bar() {
let value = 2
foo()
}

bar() // 1

上面这个例子中,foo函数中的value向上寻找为在全局定义的1,所以会打印出1

1
2
3
4
5
6
7
8
9
10
11
value=1

function foo(){
echo $value
}

function bar() {
local value=2
foo
}
bar #2

而在bash中,由于是动态作用域,所以会打印出2

Read more »

~运算符

位运算符是三步处理的过程:

  1. 把运算数转换成 32 位数字
  2. 把二进制数转换成它的二进制反码
  3. 把二进制数转换成浮点数
1
2
3
var iNum1 = 25 //25 等于 00000000000000000000000000011001
var iNum2 = ~iNum1 //转换为 11111111111111111111111111100110
alert(iNum2) //输出 "-26"

~~技巧

这是刷题时看见别人的代码里使用的东西,通常用来代替 Math.trunc()的方法。

1
2
3
4
5
6
//单个 ~
console.log(~1337) // -1338
//数字输入
console.log(~~47.11) //47
console.log(~~1.9999) //1
console.log(~~3) //3

当原始输入不确定时,~~可以将任何非数字类型转换成 0:

1
2
3
4
5
6
7
8
console.log(~~[]) //0
console.log(~~NaN) //0
console.log(~~null) //0

// | 0 也是相同的效果
console.log([] | 0) //0
console.log(NaN | 0) //0
console.log(null | 0) //0
Read more »

一个简单的处理 XML 的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function parseXml(xml) {
//跨浏览器处理 XML
var xmldom = null

if (typeof DOMParser != "undefined") {
xmldom = new DOMParser().parseFromString(xml, "text/xml")
var errors = xmldom.getElementsByTagName("parsererror")
if (errors.length) {
throw new Error("XML parsing error:" + errors[0].textContent)
}
} else if (typeof ActiveXObject != "undefined") {
xmldom = createDocument()
xmldom.loadXML(xml)
if (xmldom.parseError != 0) {
throw new Error("XML parsing error:" + xmldom.parseError.reason)
}
} else {
throw new Error("No XML parser available.")
}
return xmldom
}

序列化 XML 文档

1
2
3
4
5
6
7
8
9
10
11
12
13
//序列化 xmldom 文档
function serializeXML(xmldom) {
if (typeof XMLSerializer != "undefined") {
//兼容 ie9+ safari Chrome opera
var serializer = new XMLSerializer()
return serializer.serializeToString(xmldom)
} else if (typeof xmldom.xml != undefined) {
//兼容 ie9.0 以下
return xmldom.xml
} else {
throw new Error("serialize XML Dom failed!")
}
}

什么是微前端

微前端架构具备以下几个核心价值

  • 技术栈无关:主框架不限制接入应用的技术栈,子应用具备完全自主权
  • 独立开发、独立部署:子应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新
  • 独立运行时:每个子应用之间状态隔离,运行时状态不共享

现有解决方案

  • 路由分发(nginx)
  • npm 子包:基座负责打包构建发布,打包时集成;
  • iframe:应用之间完全独立;需要基座提供通信方案;
  • 通用中心路由基座式:完全独立;需要基座提供通信方案;使用 DOM 实现;(阿里乾坤)
  • 特定中心路由基座式:相同技术栈;复用基座公共基建内容;(美团广告业务)
Read more »