Live Note

Remain optimistic

简单的 Stack 实现

数组实现

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
class Stack {
constructor(size = 10) {
this.arr = [] // 栈
this.size = size // 最大长度
this.top = -1 // 栈顶
}

push(elem) {
if (this.top == this.size) {
this.size *= 2
}
this.arr[++this.top] = elem
return true
}

pop() {
let elem = this.arr[this.top--]
return elem
}

peekTop() {
if (this.top == -1) {
console.log("stack is empty")
return
}
return this.arr[this.top]
}

print() {
let str = ""
for (let i = 0; i <= this.top; i++) {
str += this.arr[i] + " "
}
console.log(str)
}
}
var stack = new Stack()
stack.push(1)
stack.push(2)
stack.pop()
console.log(stack.peekTop())
Read more »

Shader

WebGL 使用两种 Shader:

  • Vertex Shader:用于描述 point 的特性。
  • Fragment Shader:用于逐片处理。

Shader Program 使用的是 GLSL ES 语言,在 JS 中需要使用字符串编写,再通过函数加载进去。

WebGL 的执行流程大致为:

  1. Get canvas.
  2. Get WebGL context.
  3. Initialize vertex shader and fragment shader.
  4. Set clear color.
  5. Clear canvas.
  6. Draw.

vec4

在 GLSL ES 中,vec4类型用四维适量描述一个点的三维空间投影,(x, y, z, w)等价与三维空间的(x / w, y / w, z / w)
WebGL 坐标系统水平向右为 x 正轴,竖直向上为 y 正轴,垂直屏幕向外为 z 正轴。范围都在[-1, 1]之间。

Read more »

一个简陋的 VDOM

希望以后会慢慢完善吧…

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
let data = {
tag: "div",
children: [
{
tag: "span",
children: [
{
tag: "#text",
content: "hello world",
},
],
},
{
tag: "p",
children: [
{
tag: "#text",
content: "This is a paragraph!",
},
{
tag: "h1",
children: [
{
tag: "#text",
content: "This is a H1 tag",
},
],
},
{
tag: "h6",
children: [
{
tag: "#text",
content: "and I'm h6",
},
],
},
],
},
],
}

class VDOM {
constructor(data) {
this.tag = data.tag
this.children = data.children
this.content = data.content
}
static render(data) {
let _this = new VDOM(data)
if (_this.tag === "#text") {
return document.createTextNode(_this.content)
}
let node = document.createElement(_this.tag)
_this.children.map((child) => node.appendChild(VDOM.render(child)))
return node
}
}

let diff = (root, oldV, newV, current = 0) => {
if (!oldV) root.appendChild(newV)
else if (!newV) root.removeChild(root.childNodes[current])
else if (newV.tag !== oldV.tag || newV.content !== oldV.content)
root.replaceChild(new VDOM(newV).render(), root.childNodes[current])
// 递归判断
else
for (let i = 0; i < newV.children.length || i < oldV.children.length; i++)
diff(root.childNodes[i], oldV.children[i], newV.children[i], i)
}
document.querySelector("#root").appendChild(VDOM.render(data))

结构为:

1
2
3
4
5
6
7
8
9
10
<div id="root">
<div>
<span>hello world</span>
<p>
This is a paragraph!
<h1>This is a H1 tag</h1>
<h6>and I'm h6</h6>
</p>
</div>
</div>

某日被书中一段代码误导

1
2
3
4
5
6
7
8
9
10
11
var promise = new Promise(function (resolve, reject) {
resolve("ok")
setTimeout(function () {
throw new Error("test")
}, 0)
})
promise.then(function (value) {
console.log(value)
})
//ok
//Uncaught Error : test

由于前面还有这样一段话

如果 Promise 状态已经变成 Resolved,再抛出错误是无效的。

当时看到这,思索了许久,为什么已经 resolve 了这个 ERROR 还是可以往外抛出呢?
后面发现,settimeout 是一个异步函数,throw 会在下一轮事件循环开始时抛出,所以无论是否 resolve,这个 ERROR 都是会抛出的。

子类的原型对象-类式继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 类式继承
// parent
function SuperClass() {
this.superValue = true
}
SuperClass.prototype.getSuperValue = function () {
return this.superValue
}

// child
function SubClass() {
this.subValue = false
}
SubClass.prototype = new SuperClass()
SubClass.prototype.getSubValue = function () {
return this.subValue
}

let child = new SubClass()
console.log(child.getSuperValue()) // true
console.log(child.getSubValue()) // false
Read more »