JavaScript没有原生的继承机制,但是可以模拟实现。其中的关键是使用Function.apply()或Function.call()。自己实现了这种模拟过程,在这里记一笔。
var Utility = { trace: function(s){ WScript.Echo(s); }, getDateTime: function(){ var d = new Date(); var s = new String(); s = d.getFullYear() + "-" + (d.getMonth() + 1) + "-" + d.getDate() + " " + d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds(); return s; } }; var Class = { Inherit: function(child, parent){ for(var p in parent) { var lambda = parent[p]; if(lambda instanceof Function) { child[p] = lambda.bind(child); } } } }; Function.prototype.bind = function(obj){ var method = this; return function(){ return method.apply(obj, arguments); }; }; //BaseLogWriter不能被直接使用,只有子类继承之,并实现Write()方法后,在子类中Debug等方法才可用 var BaseLogWriter = { Debug: function(s) { var strLog = Utility.getDateTime() + " [Debug] " + s; this.Write(strLog); }, Info: function(s) { var strLog = Utility.getDateTime() + " [Info] " + s; this.Write(strLog); } }; function ConsoleLogWriter() { // 继承BaseLogWriter的方法 Class.Inherit(this, BaseLogWriter); this.Init = function() { }; this.Final = function() { }; this.Write = function(s) { WScript.Echo(s); }; } function TextLogWriter(strLogFile) { // 继承BaseLogWriter的方法 Class.Inherit(this, BaseLogWriter); this.privs = { logFile: strLogFile, fso: null, // FileSystemObject text: null // TextStream }; this.Init = function() { this.Final(); this.privs.fso = new ActiveXObject("Scripting.FileSystemObject"); this.privs.text = this.privs.fso.OpenTextFile(this.privs.logFile, 8, true); }; this.Final = function() { if(this.privs.text != null) { this.privs.text.Close(); this.privs.text = null; } if(this.privs.fso != null) { this.privs.fso = null; } }; this.Write = function(strContent) { this.privs.text.WriteLine(strContent); }; } function main(){ var cWriter = new ConsoleLogWriter(); cWriter.Init(); cWriter.Debug("test console log 1"); cWriter.Info("test console log 2"); var tWriter = new TextLogWriter("log.txt"); tWriter.Init(); tWriter.Debug("test text log 1"); tWriter.Info("test text log 2"); cWriter.Final(); tWriter.Final(); }; main();
上面这些JS代码保存至Interface.js,在windows控制台下运行cscript.exe //Nologo Interface.js,即可分别在打印和log.txt中见到运行结果:
控制台打印出:
2011-4-5 21:13:32 [Debug] test console log 1
2011-4-5 21:13:32 [Info] test console log 2
log.txt里记录是:
2011-4-5 21:13:32 [Debug] test text log 1
2011-4-5 21:13:32 [Info] test text log 2
可见实际Debug和Info里调用的Write()是各个子类中的Write()。子类中Write()实现的不同,那么Debug()和Info()的行为就不同,这和C++中多态机制类似,可见这里模拟出的继承机制是成功的。