JS.Class - 3. Modules & Mixins
2009-10-13 00:00:00 来源:WEB开发网Mixins 允许开发人员在不做继承和修改的情况下,为类型添加额外的方法。这有点像 C# 的扩展方法,但动态语言 Mixins 机制要更加灵活。记得我最初看 Ruby 的时候就被这个功能吸引过。在使用 Mixins 之前,我们需要先定义一个 Modules,它是这些扩展方法的载体和容器。
var Module = new JS.Module(
{
extend :
{
println : function(s) { document.writeln(s + "<br />"); }
},
getName : function()
{
return this.hasOwnProperty("name") ? this.name : this.toString();
}
});
var User = new JS.Class(
{
name : "User",
include : Module
});
var o = new User();
o.name = "Tom";
User.println(o.getName());
我们可以使用 JS.Module 来创建一个 Module,它可以包含静态和实例两种扩展方法,是不是很强?不过需要注意,Module 无法实例化,也无法在外部调用其静态方法。下面两种写法都会引发异常。
new Module();
Module.println("ab");
除了在目标类型使用 include 引入一个或多个 (include : [Module1, Module2]) Module 外,我们还可以直接在外部动态引入 (对已经生成的对象实例同样有效)。
var User = new JS.Class(
{
name : "User"
});
User.include(Module);
Minxins 会重写 (overwrite) 类型或对象实例中的同名方法。
var Module = new JS.Module(
{
extend :
{
println : function(s) { document.writeln("Mixins: " + s + "<br />"); }
},
test : function()
{
return "[Mixins]";
}
});
var User = new JS.Class(
{
test : function()
{
return "[User]";
},
extend :
{
println : function(s) { document.writeln("User: " + s + "<br />"); }
}
});
var o = new User();
User.println(o.test()); // User: [User]
User.include(Module);
User.println(o.test()); // Mixins: [Mixins]
要避免这种情况发生,可以使用 "include(Module, false)" 。
附注: 我使用的 1.6 版本这个参数没有起作用,似乎是个 Bug,overwirte 参数在 class.js 183 行传递过程中丢失。另外作者提到 "include 引入实例方法,extend 引入静态方法" 的说法似乎也有些问题。
JS.Class 提供了一种 Hook 机制,当一个类型被 subclassed 或 Mixins 时,类型中特定名称的静态方法将被触发。
var User = new JS.Class(
{
extend :
{
inherited : function(klass) { alert("onInherited!"); },
included : function(klass) { alert("onIncluded!"); },
extended : function(klass) { alert("onExtended!"); }
}
});
var Manager = new JS.Class(User, {});
User.include(Module);
User.extend(Module);
编缉推荐阅读以下文章
- JS.Class - 2. Methods & Types
- JS.Class - 1. Classes & Inheritance
更多精彩
赞助商链接