JS-Plugin

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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const betaCalcPre = {
currentValue: 0,

setValue(newValue) {
this.currentValue = newValue;
console.log(this.currentValue);
},

plus(addend) {
this.setValue(this.currentValue + addend);
},

minus(subtrahend) {
this.setValue(this.currentValue - subtrahend);
},

register(plugin) {
const {name, exec} = plugin;
this[name] = exec;
}
};

// In many plugin systems, it’s common for plugins to have two parts:
// Code to be executed
// Metadata (like a name, description, version number, dependencies, etc.)
const squaredPluginPre = {
name: 'squared',
exec: function() {
this.setValue(this.currentValue * this.currentValue)
}
}

betaCalcPre.register(squaredPluginPre);
/*
缺点:
1. 插件能访问父类this,违反 the open-closed principle,能直接修改父类的方法,导致出现不可预期行为
2. 插件提供的squared方法产生了副作用,引用不透明
*/

betaCalcPre.setValue(3); // => 3
betaCalcPre.plus(2); // => 5
betaCalcPre.squared(); // => 25
betaCalcPre.squared(); // => 625



const betaCalc = {
currentValue: 0,

setValue(value) {
this.currentValue = value;
console.log(this.currentValue);
},

core: {
'plus': (currentVal, addend) => currentVal + addend,
'minus': (currentVal, subtrahend) => currentVal - subtrahend
},

// plugins members can't access betaCalc this
plugins: {},

// change to pure functions
press(buttonName, newVal) {
const func = this.core[buttonName] || this.plugins[buttonName];
this.setValue(func(this.currentValue, newVal));
},

register(plugin) {
const { name, exec } = plugin;
this.plugins[name] = exec;
}
};

const squaredPlugin = {
name: 'squared',
exec: function(currentValue) {
return currentValue * currentValue;
}
};

betaCalc.register(squaredPlugin);

betaCalc.setValue(3); // => 3
betaCalc.press('plus', 2); // => 5
betaCalc.press('squared'); // => 25
betaCalc.press('squared'); // => 625
参考链接
  1. https://css-tricks.com/designing-a-javascript-plugin-system/