JavaScript object-oriented implementation without the Constructor new Keyword

Source: Internet
Author: User

The object model in JavaScript is not widely known. I once wrote a blog about them. 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 languages such as CoffeeScript, Dart, and TypeScript can generate JS Code through compilation appear.

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 expert Nicholas Zakas welcomed the new class syntax added to ECMAScript 6-just to make some modifications to the prototypal style syntax. In other words, traditional OOP won.

A bold idea
However, let's make an assumption in a joke: we imagine that we had crossed the past. At that time, the traditional object-oriented programming was not as widely accepted as it is now. On the contrary, the prototype-based inheritance model is 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:
Copy codeThe Code is as follows:
Var felix = {
Name: 'Felix ',
Greet: function (){
Console. log ('Hello, I am '+ this. name + '.');
}
};

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, adding 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 an "augment" function to implement it, and we will see the code:
Copy codeThe Code is as follows:
Var Dude = {
Greet: function (){
Console. log ('Hello, I am '+ this. name + '.')
}
};
Var felix = {name: 'Felix '};
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:
Copy codeThe Code is as follows:
Function augment (obj, properties ){
For (var key in properties ){
Obj [key] = properties [key];
}
}

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:
Copy codeThe Code is as follows:
Var Dude = {
Greet: function (){
Console. log ('Hello, I am '+ this. name + '.');
}
}
Var felix = clone (Dude); // clone Dude object
Felix. 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.
Copy codeThe Code is as follows:
Var felix = clone (Dude );
Felix. name = 'Felix ';
Felix. greet = function (){
Console. log ('Yo dawg! ');
}; // Override the greet Method

The method to call the parent class is also very easy-use the apply function, as shown below:
Copy codeThe Code is as follows:
Felix. greet = function (){
Dude. greet. apply (this );
This. greetingCount ++;
}

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:
Copy codeThe Code is as follows:
Function clone (obj ){
Var retval ={}; // create an empty object
Augment (retval, obj); // copy attributes
Return retval;
}

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.
Copy codeThe Code is as follows:
Var felix = inherit (Dude );
Felix. 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,
Copy codeThe Code is as follows:
Var garfield = inherit (Dude); // garfield inherits from Dude
Dude. walk = function () {// Add a new method to the Dude
Console. log ('step, step ');
};
Garfield. walk (); // prints "Step, step"
Felix. walk (); // also prints "Step, step"

The inherit function uses prototype-based object inheritance.
Copy codeThe Code is as follows:
Function inherit (proto ){
If (Object. create ){
// Use the Object. create method in ES5
Return Object. create (proto );
} Else if ({}. _ proto __){
// Use non-standard attribute _ proto __
Var ret = {};
Ret. _ proto _ = proto;
Return ret;
} Else {
// If neither of them is supported, use the constructor to inherit
Var f = function (){};
F. prototype = proto;
Return new f ();
}
}

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, using an initialization method called initialize. Assume that an initialize method is defined in Dude, as shown below:
Copy codeThe Code is as follows:
Var Dude = {
Initialize: function (){
This. greetingCount = 0;
},
Greet: function (){
Console. log ('Hello, I am '+ this. name + '.');
This. greetingCount ++;
}
}

Then, you can initialize the object in this way.
Copy codeThe Code is as follows:
Var felix = clone (Dude );
Felix. name = 'Felix ';
Felix. initialize (); or you can
Var felix = {name: 'Felix '};
Felix. name = 'Felix ';
Augment (felix, Dude );
Felix. initialize ();
Var felix = inherit (Dude );
Felix. name = 'Felix ';
Felix. 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.