Constructor can be used to implement JavaScript object-oriented functions.

Source: Internet
Author: User

Original article:Javascript oo without Constructors

The object model in Javascript is not widely known. I wrote an article aboutThey. Javascript is the only language widely used to inherit from prototype. However, I think another reason is that this object model is very complex and difficult to explain. Why is it so complicated and confusing? That's because JavaScript tries to hide its traditional object-oriented feature, which eventually leads to its dual personality, also has object-oriented features ).

I think it is because of the difficulty of understanding and using JavaScript Object Models that some JavaScript files such as coffeescript, dart, and typescript can be generated through compilation.CodeLanguage.

The predecessors of JavaScript and those stubborn writers believe that JavaScript has a better object model and feel sorry that it will be forgotten. Even JavaScript expertsNicolas zakasYou are also welcome to join ecmascript 6.New Class syntax-- Just for the prototype (Prototypal Style. In other words, traditional OOP won.

A bold idea

However, let's make an assumption in a joke: we assume that we have crossed the past, when the traditional object-orientedProgramThe design has not been as widely accepted as it is now. On the contrary, the prototype-based inheritance model has been widely accepted. So what will happen? What kind of design patterns will we finally get?

Let's imagine: What if Javascript does not have a constructor or a new keyword? What Will things become? Let's start from the past. :)

First, the first thing is that in Javascript, we can use the object literal to create a new object. As follows:

1 VaRFelix ={2Name: 'Felix',3Greet:Function(){4Console. Log ('Hello, I am' +This. Name + '.');5 }6};

Next, let's assume that we want to generalize the GREET function, extract it, and place it in a general position. In this way, we can create multiple objects to share the same greet method. How can this problem be achieved?

We have several options. Let's start with Mixin.

1. Mixed (Object expansion) Mixin (augmentation)

in Javascript, mixing attributes is very simple. You only need to copy the properties of the mixed object to the object to be mixed in. We will use the " augment " function to implement it. We can see the code:

  1   var  dude = {  2  greet:  function   () {  3  console. log ('Hello, I am '+  This . name + '. ')   4  }  5  };   6   var  Felix = {Name: 'Felix '};   7  augment (Felix, dude );  //   copy the attributes in dude to Felix, that is, mix (Mixin)  

In the code above, the augment function blends the attributes of the dude object into Felix. In many JS libraries, the augment function is called extend. I don't like extend because some languages use extend to represent inheritance, which makes me very confused. I prefer to use "augment", because in fact this practice is not inherited, And the syntax augment (Felix, dude) it is clear that you use the attributes in dude to expand Felix, rather than inherit.

Maybe you have long guessed the augment code implementation. That's right, it's very simple. As follows:

 
1 FunctionAugment (OBJ, properties ){2For(VaRKeyInProperties ){3OBJ [Key] =Properties [Key];4 }5}

2. Object cloning (cloning)

An alternative to Mixin is to first clone the dude object and then set the name attribute for the cloned object. As follows:

 
1 VaRDude ={2Greet:Function(){3Console. Log ('Hello, I am' +This. Name + '.');4 }5 }6 VaRFelix = clone (dude );//Clone dude object7Felix. Name = 'Felix ';

The only difference between the two methods is the order of adding attributes. If you want to override some methods in the cloned object, you can consider using this method.

1 VaRFelix =Clone (dude );2Felix. Name = 'Felix ';3Felix. Greet =Function(){4Console. Log ('Yo dawg! ');5};//Override greet Method

The method to call the parent class is also very easy-use the apply function, as shown below:

1Felix. Greet =Function(){2Dude. Greet. Apply (This);3This. Greetingcount ++;4}

This is much better than the prototype code, because you don't have to use the. Prototype attribute of the constructor-we don't use any constructor.

The following is the implementation of the clone function:

1 FunctionClone (OBJ ){2VaRRetval = {};//Create an empty object3Augment (retval, OBJ );//Copy attributes4ReturnRetval;5}

3. Inheritance)

Finally, it is inherited. In my opinion, inheritance is overestimated, but inheritance does have some advantages over object expansion in sharing attributes between "instance objects. Let's write an inherit function, which receives an object as a parameter and returns a new object inherited from this object.

1 VaRFelix =Inherit (dude );2Felix. Name = 'Felix ';

With inheritance, you can create multiple sub-objects that inherit from the same object. These Sub-objects can inherit the attributes of the parent object in real time. The following code shows,

1 VaRGarfield = inherit (dude );//Garfield inherited from dude2Dude. Walk =Function(){//Add a new method to dude3Console. Log ('step, step');4 };5Garfield. Walk ();//Prints "Step, step"6Felix. Walk ();//Also prints "Step, step"

The inherit function uses prototype-based object inheritance.

 1  Function  Inherit (PROTO ){  2       If  (Object. Create ){  3           //  Use the object. Create method in es5  4           Return  Object. Create (PROTO );  5 } Else   If  ({}. _ PROTO __){  6          //  Use non-standard attribute _ PROTO __  7           VaR Ret = {};  8 Ret. _ PROTO _ = PROTO;  9           Return  RET;  10 } Else  {  11           //  If neither of them is supported, use constructor to inherit 12           VaR F = Function  (){};  13 F. Prototype = PROTO;  14           Return   New  F ();  15   }  16 }

The above Code does not look very good, because we use feature monitoring to determine which of the three methods to use.

But how to use the constructor (that is, the initialization method )? How do you share the initialization code between instance objects? In some cases, if you only need to set some attributes for the object, the initialization function is not necessary at this time, as in the above example. But if you have more initialization code, you may make a Convention, for example, usingInitialize initialization method. Let's assume that in dude we defineThe initialize method is as follows:

 1   VaR Dude = {  2 Initialize: Function  (){  3           This . Greetingcount = 0 ;  4   },  5 Greet:Function  (){  6 Console. Log ('Hello, I am' + This . Name + '.' );  7           This . Greetingcount ++ ;  8   }  9 }

Then, you can initialize the object in this way.

1 VaRFelix =Clone (dude );2Felix. Name = 'Felix';3Felix. initialize ();

Or

 
1 VaRFelix = {Name: 'Felix'};2Felix. Name = 'Felix';3 Augment (Felix, dude );4Felix. initialize ();

Yes

1 VaRFelix =Inherit (dude );2Felix. Name = 'Felix';3Felix. initialize ();

Conclusion

Using the three functions defined above-augment, clone, and inherit, you can do anything you want to do with objects in Javascript without using constructors and new keywords. I think the semantics of these three functions is simpler and closer to the object system at the bottom of JavaScript.

(End) ^_^

 

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.