如何在JavaScript中模拟类(和命名空间)?
我需要创建一个JavaScript库,并且对该语言的使用经验有限.我一直认为它对类有本机支持,但它与Java的相关性低于我的假设.似乎JavaScript中的所有内容实际上都是一个函数.
到目前为止我发现它是一种动态的弱类型语言很有意义,但这对于那些习惯使用强类型语言并使用编译器来发现错误的人来说有点偏离: )
我主要使用C#和Java,并且希望语法类似,所以对于我们需要维护它的其他C#开发人员来说,这个库看起来很熟悉.
我有以下类型的代码可以工作,但我想知道其他开发人员将采取什么措施.有哪些替代方案?有没有更好的方法?有没有更可读的方法?
我明白我想要的是类似于C#或Java的东西,我应该接受这个是JavaScript的事实,但我的目标是通过让它更熟悉和直观来减轻其他开发人员的学习曲线.
//Perform the namespace setup (this will actually be done with checking //in real life so we don't overwrite definitions, but this is kept short //for the code sample). var DoctaJonez = new function(); DoctaJonez.Namespace1 = new function(); /** * Class description. */ DoctaJonez.Namespace1.SomeClass = function() { /** * Public functions listed at the top to act like a "header". */ this.publicFunction = privateFunction; /** * Private variables next. */ var privateVariable; /** * Finally private functions. */ function privateFunction() { } } //Create an instance of the class var myClass = new DoctaJonez.SomeClass(); //Do some stuff with the instance myClass.publicFunction();
mepcotterell.. 15
3种定义JavaScript类的方法
面向对象的JavaScript
JavaScript教程:函数和类
Eugene Lazut.. 10
为了在JavaScript中对OOP的一般理解,你不能比阅读Douglas Crockford更好:
JavaScript中的经典继承
JavaScript中的原型继承
JavaScript中的私人会员
对于Dojo粉丝(以及一般技术),Neil Roberts有很好的文章:
数字颜色:dojo.delegate
JavaScript元类编程
Plain vanilla dojo.declare()可能是主流图书馆中最先进的OOP基础.我有偏见,但不接受我的话.以下是如何使用它的示例.
普通的香草物:
// Let's define a super simple class (doesn't inherit anything). dojo.declare("Person", null, { // Class-level property answer: 42, // Class-level object property name: {first: "Ford", last: "Prefect"}, // The constructor, duh! constructor: function(age){ this.age = age; // instance-level property }, // A method saySomething: function(verb){ console.log("I " + verb + " " + this.name.first + " " + this.name.last + "!" + " -- " + this.answer); }, // Another method passportControl: function(){ console.log("I am " + this.age); } });
使用示例:
// A fan of Ford Perfect var fan = new Person(18); fan.saySomething("love"); // I love Ford Perfect! -- 42 fan.passportControl(); // I am 18
单继承很容易:
// Let's create a derived class inheriting Person dojo.declare("SuperAgent", Person, { // Redefine class-level property answer: "shaken, not stirred", // Redefine class-level object property name: {first: "James", last: "Bond"}, // The constructor constructor: function(age, drink){ // We don't need to call the super class because // it would be done automatically for us passing // all arguments to it. // At this point "age" is already assigned. this.drink = drink; // Instance-level property }, // Let's redefine the method saySomething: function(verb){ // Let's call the super class first this.inherited(arguments); // Pay attention: no need for extra parameters, or any extra code, // we don't even name the class we call --- it is all automatic. // We can call it any time in the body of redefined method console.log("Yeah, baby!"); }, shoot: function(){ console.log("BAM!!!"); } });
使用示例:
// Let's create a James Bond-wannabe var jb007 = new SuperAgent(45, "Martini"); jb007.saySomething("dig"); // I dig James Bond! -- shaken, not stirred // Yeah, baby! jb007.passportControl(); // I am 45 jb007.shoot(); // BAM!!! // Constructors were called in this order: Person, SuperAgent // saySomething() came from SuperAgent, which called Person // passportControl() came from Person // shoot() came from SuperAgent.
混入:
// Let's define one more super simple class dojo.define("SharpShooter", null, { // For simplicity no constructor // One method to clash with SuperAgent shoot: function(){ console.log("It's jammed! Shoot!"); } });
基于Mixin的多重继承:
// Multiple inheritance dojo.declare("FakeAgent", ["SuperAgent", "SharpShooter"], { // Let's do it with no constructor // Redefine the method saySomething: function(verb){ // We don't call super here --- a complete redefinition console.log("What is " + verb "? I want my " + this.drink + "!"); }, });
使用示例:
// A fake agent coming up var ap = new FakeAgent(40, "Kool-Aid"); ap.saySomething("hate"); // What is hate? I want my Kool-Aid! ap.passportControl(); // I am 40 ap.shoot(); // It's jammed! Shoot! // Constructors were called in this order: Person, SuperAgent // saySomething() came from FakeAgent // passportControl() came from Person // shoot() came from SharpShooter.
正如您所看到的,dojo.declare()
为所有必需品提供了一个简单易用的API:直接单继承,基于mixin的多重继承,构造函数的自动链接,以及无麻烦的超级方法.
3种定义JavaScript类的方法
面向对象的JavaScript
JavaScript教程:函数和类
为了在JavaScript中对OOP的一般理解,你不能比阅读Douglas Crockford更好:
JavaScript中的经典继承
JavaScript中的原型继承
JavaScript中的私人会员
对于Dojo粉丝(以及一般技术),Neil Roberts有很好的文章:
数字颜色:dojo.delegate
JavaScript元类编程
Plain vanilla dojo.declare()可能是主流图书馆中最先进的OOP基础.我有偏见,但不接受我的话.以下是如何使用它的示例.
普通的香草物:
// Let's define a super simple class (doesn't inherit anything). dojo.declare("Person", null, { // Class-level property answer: 42, // Class-level object property name: {first: "Ford", last: "Prefect"}, // The constructor, duh! constructor: function(age){ this.age = age; // instance-level property }, // A method saySomething: function(verb){ console.log("I " + verb + " " + this.name.first + " " + this.name.last + "!" + " -- " + this.answer); }, // Another method passportControl: function(){ console.log("I am " + this.age); } });
使用示例:
// A fan of Ford Perfect var fan = new Person(18); fan.saySomething("love"); // I love Ford Perfect! -- 42 fan.passportControl(); // I am 18
单继承很容易:
// Let's create a derived class inheriting Person dojo.declare("SuperAgent", Person, { // Redefine class-level property answer: "shaken, not stirred", // Redefine class-level object property name: {first: "James", last: "Bond"}, // The constructor constructor: function(age, drink){ // We don't need to call the super class because // it would be done automatically for us passing // all arguments to it. // At this point "age" is already assigned. this.drink = drink; // Instance-level property }, // Let's redefine the method saySomething: function(verb){ // Let's call the super class first this.inherited(arguments); // Pay attention: no need for extra parameters, or any extra code, // we don't even name the class we call --- it is all automatic. // We can call it any time in the body of redefined method console.log("Yeah, baby!"); }, shoot: function(){ console.log("BAM!!!"); } });
使用示例:
// Let's create a James Bond-wannabe var jb007 = new SuperAgent(45, "Martini"); jb007.saySomething("dig"); // I dig James Bond! -- shaken, not stirred // Yeah, baby! jb007.passportControl(); // I am 45 jb007.shoot(); // BAM!!! // Constructors were called in this order: Person, SuperAgent // saySomething() came from SuperAgent, which called Person // passportControl() came from Person // shoot() came from SuperAgent.
混入:
// Let's define one more super simple class dojo.define("SharpShooter", null, { // For simplicity no constructor // One method to clash with SuperAgent shoot: function(){ console.log("It's jammed! Shoot!"); } });
基于Mixin的多重继承:
// Multiple inheritance dojo.declare("FakeAgent", ["SuperAgent", "SharpShooter"], { // Let's do it with no constructor // Redefine the method saySomething: function(verb){ // We don't call super here --- a complete redefinition console.log("What is " + verb "? I want my " + this.drink + "!"); }, });
使用示例:
// A fake agent coming up var ap = new FakeAgent(40, "Kool-Aid"); ap.saySomething("hate"); // What is hate? I want my Kool-Aid! ap.passportControl(); // I am 40 ap.shoot(); // It's jammed! Shoot! // Constructors were called in this order: Person, SuperAgent // saySomething() came from FakeAgent // passportControl() came from Person // shoot() came from SharpShooter.
正如您所看到的,dojo.declare()
为所有必需品提供了一个简单易用的API:直接单继承,基于mixin的多重继承,构造函数的自动链接,以及无麻烦的超级方法.