小型项目还是 Backbone 用起来比较舒心,所以写着写着又开始用它了。这次还用到 ES2015 和 Babel,于是疑问就来了:怎么在 ES2015 下使用 Backbone 呢?
普通用法
Backbone 自带 .extend()
方法,在早期的蛮荒岁月可以帮我们方便的创建各种子类。
var MyView = Backbone.View.extend({
events: {
},
tagName: 'div',
initialize: function () {
}
});
以前这样确实很方便,代码也很好读。但是 ES2015 引入了新的 Class 规范,写出来是这样婶儿的:
class MyView extends Backbone.View {
// 其实不能这样写
tagName: 'div'
events: {
}
// 上面这样写是不对的
constructor() {
}
}
这个时候问题来了。ES2015 不支持直接声明类属性,也就是上面代码中的 tagName
和 events
,是不能这样写的。因为它实际上只是重新包装了原型继承那一套东西,所以上面的代码实际上等效于:
MyView = function () {
}
MyView.prototype = new Backbone.View();
MyView.prototype.tagName = 'div';
MyView.prototype.events = {
};
这样的结果,不同实例间实际在共享方法和属性,包括 tagName
和 events
。如果是简单对象,比如字符串和数字,用 =
赋值还好;如果是复杂对象,比如数组,就很容易出问题。
Backbone 1.0 之前也会有这个问题,但是忘记从哪个版本开始就修复了。
新的用法
想要在 ES2015 中继续 Backbone 当然也是可以的。目前看来有三种方式:
- 把属性转化为方法。Backbone 对属性的处理都是委托给
_.result()
,所以属性和方法的效果是一样的。 - 继续使用
MyClass.prototype.someProp = 'value';
。 - 将初始化对象放在构造函数中。
我个人比较喜欢第三种方法,因为它更接近之前的写法,而且结合 Babel、Webpack 等编译打包工具,也可以做到私有。
class MyView extends Backbone.View {
constructor(init) {
super(_.extend(init, {
events: {
},
tageName: 'div'
});
}
}
未来,ES2016
ES2016 中引入了很重要的 Decorators 概念,顾名思义,它会显式的告诉运行时下面是些什么东西,那么运行时自然也就可以按照对应的规则去处理。
@props({
tagName: 'div',
events: {
}
})
class MyView extends Backbone.View {
constructor(init) {
super(init);
}
}
参考文章
本篇内容主要参考自以下两篇:
欢迎吐槽,共同进步