Decorator 装饰器模式

e.g.

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
let worker = {
someMethod() {
return 1
},

slow(x) {
console.log("called with " + x)
return x * this.someMethod()
},
}

function decorator(func) {
const cache = new Map()

return function (x) {
if (cache.has(x)) {
console.log("cache hit")
return cache.get(x)
}

const result = func.call(this, x)
cache.set(x, result)

return result
}
}

worker.slow = decorator(worker.slow)

console.log(worker.slow(2))
console.log(worker.slow(2))

Injection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function injection(func, ...argsBound) {
return function (...args) {
return func.call(this, ...argsBound, ...args)
}
}

// usage
let user = {
firstName: "Edward",
say(time, phrase) {
console.log(`[${time}]: ${this.firstName} ${phrase}`)
},
}

user.say = injection(
user.say,
new Date().getHours() + ":" + new Date().getMinutes()
)

user.say("Hi")

arrow function

1
2
3
4
5
6
7
8
9
10
11
12
function defer(f, ms) {
return function () {
setTimeout(() => f.apply(this, arguments), ms)
}
}

function sayHello(name) {
console.log(`Hi, ${name}`)
}

const deferSay = defer(sayHello, 2000)
deferSay("Edward")

prototype

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let user = {
name: "Edward",
hello(name) {
console.log(`hi ${this.name}, this is ${name}`)
},
}

Function.prototype.defer = function (ms) {
let f = this
return function (...arg) {
setTimeout(() => f.apply(this, arg), ms)
}
}

user.hello = user.hello.defer(1000)
user.hello("Ejklfj")