Live Note

Remain optimistic

起因

许久未使用mac,然后发现在terminal里使用code <name>的时候,报错了。

1
2
/usr/local/bin/code: line 6: /usr/bin/python: No such file or directory
/usr/local/bin/code: line 10: ./MacOS/Electron: No such file or directory

后面才发现,系统里只有python3,没有python,遂在/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code中将python修改为python3得以解决。

ES6 提供了 Map 数据结构,它类似对象,也是键值对的集合,但是‘键’的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map 结构是一种更完善的 Hash 结构实现。如果需要‘键值对’的数据结构,Map 比 Object 更合适。

1
2
3
4
let m = new Map()
const o = { p: "hello" }
m.set(o, "content")
m.get(o) //'content'

Map 也可以接受一个数组作为参数,该数组的成员是一个表示键值对的数组:

1
2
3
4
5
6
7
8
const map = new Map([
["name", "张三"],
["title", "test"],
])

map.size //2
map.has("name") //true
map.get("name") //'张三'

Map 构造函数接受数组作为参数,实际上执行的是下面的算法:

1
2
3
4
5
6
const item = [
["name", "张三"],
["title", "test"],
]
const map = new Map()
item.forEach(([key, valule]) => map.set(key, value))
Read more »

Math.trunc()

Math.trunc 用于除去一个数的小数部分。

1
2
3
4
5
6
7
8
9
10
11
Math.trunc(111.22) //111
Math.trunc("123.456") //123
//对空和无法截取整数的值,返回 NaN
Math.trunc(NaN) //NaN

//代码模拟
Math.trunc =
Math.trunc ||
function (x) {
return x < 0 ? Math.ceil(x) : Math.floor(x)
}
Read more »

Mix-ins

Abstract subclasses or mix-ins are templates for classes. An ECMAScript class can only have a single superclass, so multiple inheritance from tooling classes, for example, is not possible. The functionality must be provided by the superclass.

eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const calculatorMixin = (Base) =>
class extends Base {
calc() {
// do something
}
}

const randomizerMixin = (Base) =>
class extends Base {
remdomize() {
// do something
}
}

class Foo {}
class Bar extends calculatorMixin(randomizerMixin(Foo)) {}
const bar = new Bar()
console.log(bar.calc)
console.log(bar.remdomize) // also a function.

Container

Let’s create a normal container first.

1
2
3
4
5
6
7
8
9
10
11
class Container {
constructor(x) {
this._value = x
}
// use the of to create the container
static of(x) {
return new Container(x)
}
}
Container.of(2) // Container { _value: 2 }
Container.of({ name: "jack" }) // Container { _value: { name: 'jack' } }

But we should not directly manipulate the data in the container. We need a function to do this.

1
2
3
4
5
6
// Container.prototype.map :: (a -> b) -> Container a -> Container b
Container.prototype.map = function (f) {
return Container.of(f(this._value))
}
let six = Container.of(2).map((x) => x * 3) // Container { _value: 6 }
six.map((x) => x.toString()).map((x) => "number: " + x + "!") // Container { _value: 'number: 6!' }

After passing the values in the Container to the map function, we can let them manipulate it; after the operation is completed, in order to prevent accidents, put them back into the Container they belong to. The result is that we can call the map continuously, running any function we want to run.
And the Functor is a container type that implements the map function and adheres to certain rules.

Maybe

In Haskell, the Maybe type is defined as follow:

1
data Maybe a = Just a | Nothing

Maybe will check if its value is empty before calling the passed function. So let’s create a simple one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Maybe {
constructor(x) {
this._value = x
}
static of(x) {
return new Maybe(x)
}
isNothing() {
return this._value === null || this._value === undefined
}
// map :: (a -> b) -> Maybe a -> Maybe b
map(f) {
return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this._value))
}
}
Maybe.of("hello world").map(match(/o/gi)) // Maybe { _value: [ 'o', 'o' ] }
Maybe.of({ name: "jack" })
.map($.prop("age"))
.map((x) => x + 10) // Maybe { _value: null }
Read more »