Introduction to a simple JavaScript class framework

Source: Internet
Author: User
Tags constructor extend function prototype inheritance

This article mainly introduces a simple JavaScript class framework, which helps beginners to understand the creation and inheritance of JS class, the need for friends can refer to the

In writing work-in-progress JavaScript book, I spent a considerable amount of time on the JavaScript inheritance system, and studied various scenarios for simulating classical class inheritance in the process. In these technical projects, I most highly esteem is the BASE2 and the prototype realization.

From these solutions, one should be able to extract a framework with its own ideological connotation, which must be simple, reusable, easy to understand and not dependent, where simplicity and usability are the focus. The following are examples of usage:

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27-28 var person = Class. Extend ({init:function (isdancing) {this. dancing = isdancing;}, Dance:function () {return this. dancing;}}); var Ninja = Person.extend ({init:function () {This._super (false);}, Dance:function () {//Call the inherited version O F Dance () return This._super (); }, Swingsword:function () {return true;}}); var p = new Person (true); P.dance (); => true var n = new Ninja (); N.dance (); => false N.swingsword (); => true//Should All is true P instanceof person && p instanceof Class && n instanceof Ninja && Amp n instanceof person && n instanceof Class

There are a few things to note:

Constructors need to be simple (implemented by the INIT function),

The new defined analogy must inherit from the existing class,

All of the ' classes ' are inherited from the Ancestor class: class, so if you want to create a completely new class, the class must be a subclass of class,

The most challenging point is that the parent class's overridden method must be accessible (by configuring the context).

In the above example, you can see that the init () and Dance () methods of the person's parent class are invoked by This._super ().

Be quite satisfied with the result: make the definition of a class structured, maintain a single inheritance, and be able to call superclass methods.

Simple class creation and inheritance

Here's how it's implemented (easy to read and commented on), about 25 lines. We welcome and thank you for your suggestions.

?

* * Simple JavaScript inheritance * by John resig http://ejohn.org/* MIT licensed. ///Inspired by BASE2 and Prototype (function () {var initializing = false, Fntest =/xyz/.test (function () {xyz;})?/ b_superb/:/.*/; The base Class implementation (does nothing) this. Class = function () {};  //Create A new class that inherits from this class class.extend = function (prop) {var _super = This.prototype; &n Bsp Instantiate a base class (but only create the instance,//don ' t run the init constructor) initializing = true; var prototype = new This (); initializing = false;  //Copy the properties over onto the "new prototype for" (Var name in prop) {//Check if we ' re overwriting an Existi ng function Prototype[name] = typeof Prop[name] = = "function" && typeof _super[name] = = "function" && fntest.test (prop[name))? (function (name, FN) {return function () {var tmp = This._super;  //Add a new. _super () method, the same meth OD//But on the super-class this._super = _super[name];  //The method is only need to is bound temporarily, so we/remove it when we do executing var ret = fn.apply (th is, arguments); This._super = tmp;   RETURN ret; }; }) (name, Prop[name]): Prop[name]; }  //The Dummy class constructor function class () {//All construction are actually done with the Init method if (!i Nitializing && this.init) this.init.apply (this, arguments); }  //Populate our constructed prototype object Class.prototype = prototype;  //enforce the constructor to be what we expect Class.prototype.constructor = Class; And make this class extendable class.extend = Arguments.callee;   return Class; }; })();

where "initialization (Initializing/don ' t call init)" and "Create _super method" are most tricky. Next, I will do a brief introduction, so that the implementation of its mechanism can be better understood.

Class

In order to illustrate the inheritance of function prototype, first look at the traditional implementation process, the subclass of the prototype attribute point to an instance of the parent class. As shown below:

?

1 2 3 4 5 function person () {} function Ninja () {} Ninja. prototype = new person (); Allows for instanceof to work: (New Ninja ()) instanceof person

However, the challenge here is that we just want to get the effect of ' whether an instance (instatnceof) ', without having to instantiate a person and invoke its constructor. To prevent this, set a bool parameter initializing in the code, and the value is true only if the parent class is instantiated and configured to the prototype property of the subclass. The purpose of this process is to distinguish between the actual instantiation and the design inheritance, and to invoke the Init method when True instantiation:

?

1 2 if (!initializing) this.init.apply (this, arguments);

It is worth noting that it is absolutely necessary to make a distinction because it is possible to run code that would rather cost resources (such as connecting servers, creating DOM elements, etc.) in the INIT function.

Super class methods (Super Method)

The most common requirement when using inheritance is that subclasses can access methods that are overridden by superclass. In this implementation, the Final solution is to provide a temporary method (. _super) that points to the superclass method and can only be accessed in the subclass method.

?

1 2 3 4 5 6 7 8 9 10 11 12 13-14 var person = Class. Extend ({init:function (isdancing) {this. dancing = Isdancing;}}); var Ninja = Person.extend ({init:function () {This._super (false);}}); var p = new Person (true); p.dancing; => true var n = new Ninja (); n.dancing; => false

Implementing this functionality requires a few steps. First, we use extend to combine the basic person instance (the class instance, which we mentioned above for its construction) and the literal object (Person.extend () function arguments). During the merge process, a simple check was made: first check whether the property that will be merged is a function, such as a function, and then check that the superclass attribute that will be overwritten is also a function? If both checks are true, you need to prepare the _super method for the property.

Note that an anonymous closure (returning a Function object) is created here to encapsulate the added super method. Based on the need to maintain the running environment, we should save the old This._super (whether it exists or not) for the function to reset after it has been run, which will help to have an unpredictable problem with the same name (not wanting to accidentally lose the object pointer).

Then, create a new _super method that only points to the overridden method in the superclass. Thankfully, you don't have to make any changes or changes to the _super, because the execution environment of the function will automatically change as the function calls the object (pointer this will point to the superclass).

Finally, the method that invokes the literal object may use This._super (), and after the method executes, resets the property _super back to its original state, then returns the function.

There are a number of scenarios where you can achieve the same effect (I've seen the super bind to itself and then access it with Arguments.callee), but it feels like this is the best way to show usability and simplicity.

Of the many JavaScript prototypes I've done, only this class of inheritance implementations I've been publishing to share with you. I think that simple code (easy to learn, easy to inherit, less to download) needs to be explored, so it's a good starting point for people who learn JavaScript classes to build and inherit.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.