假如让你开放插件,需要将上个插件的内容传入,然后将处理过后的内容传给下一个插件,要怎么实现呢?
function pluig1(Parser) {
return class class1 extends Parser {
constructor() {
super()
console.log('class1 实例化')
}
parse(program) {
console.log(program)
return(super.parse(program + 1))
}
}
}
function pluig2(Parser) {
return class class2 extends Parser {
constructor() {
super()
console.log('class2 实例化')
}
parse(program) {
console.log(program)
return(super.parse(program + 2))
}
}
}
const newParser = Parser.extend(pluig1, pluig2);
newParser.parse(3);
实现方式
首先定义一个Parser类,定义两个静态方法,注意静态方法能被继承
class Parser{
static extend() {
// ...
}
static create(input, options) {
// ..
}
parse(program) {
return program
}
}
extend
注意插件的格式:接收上一个class,然后继承它,再返回继承的class
static extend() {
var plugins = [], len = arguments.length;
while ( len-- ) plugins[ len ] = arguments[ len ];
var cls = this;
for (var i = 0; i < plugins.length; i++) { cls = plugins[i](cls); }
return cls
};
比如这是插件 class1,它继承了Parser,下一个插件class2,它继承了class1,那么原型链就形成了
Parser -> class1 -> class2
extend的最终结果是class2
parse
static create(input, options) {
return new this(options, input).parse()
};
此时class2有这两个静态方法,一个继承,一个创建实例。
然后执行newParser.parse(3),也就是class2.parse(3)
进入到static parse 里面,会新建class2的实例对象
新建class2的实例对象时,会顺着原型链依次新建 class1-Parser的实例对象
然后调用class2Instance.parse,将0传入,经过处理将结果2返回给class1Instance.parse
class1Instance.parse将处理结果3返回给Parser.parse
总结
acorn 就是用类似的方式写插件的,webpack loader 放在数组后面的先拿code也是这个原因