About JavaScript defining classes and objects in several ways _js object-oriented

Source: Internet
Author: User
Tags advantage
Take a look at this example:
Copy Code code as follows:

var a = ' global ';
(function () {
alert (a);
var a = ' local ';
})();


The first thing you see in this example is what does the output look like? ' Global '? or ' local '? In fact, is not, the output is undefined, do not confuse, my topic is to talk about this thing.
In fact, it is very simple to look at the operating mechanism of JavaScript will understand. We can think of this phenomenon as a "pre-declaration". But if you delve a little deeper, you'll understand better.
This actually involves the object attribute binding mechanism. Because all JavaScript functions are an object. A variable declared in a function can be viewed as a "similar property" of this object. The binding of an object property is divided between "early bound" and "late binding" in the language.

"Early binding"
Refers to defining its properties and methods before instantiating an object. can be converted to machine code in advance when parsing a program. The usual strongly typed languages, such as C++,java, are all early binding mechanisms. JavaScript is not a strongly typed language. It uses the "late binding" mechanism.
"Late binding"
means that you do not need to check the object type before the program runs, as long as you check that the object supports attributes and methods. You can perform a large number of operations on an object without any penalty before binding.
The above code appears in the "pre-declaration" phenomenon, we can greatly use the "late binding" mechanism to explain. In the scope of a function, all variables are "late bound". That is, the declaration is top-level. So the code above is consistent with the following:
Copy Code code as follows:

var a = ' global ';
(function () {
var A;
alert (a);
A = ' local ';
})();

Only a declaration was made to a before alert (a) and no value was assigned. So the results are predictable.

<!--digression to this end-->
RT: What this article is saying is that in JavaScript, I know several ways to define classes and objects: <! --statement: Most of the following comes from "JavaScript advanced Programming", but the individual narrative way is different-->
"Direct Volume Method"
Using direct volume to build objects is the most basic way, but there are many drawbacks.
Copy Code code as follows:

var Obj = new Object;
Obj.name = ' sun ';
Obj.showname = function () {
Alert (' THIS.name ');
}

We built an object obj, which has a property name, a method showname. But what if we're going to build a similar object? Do you want to repeat it again?
No! , we can implement it with a factory function that returns a particular type of object. Like a factory, the output of an assembly line is the specific type of result we want.
"Factory mode"
Copy Code code as follows:

function Createobj (name) {
var tempobj = new Object;
Tempobj.name = name;
Tempobj.showname = function () {
alert (this.name);
};
return tempobj;
}
var obj1 = createobj (' Obj_one ');
var obj2 = createobj (' Obj_two ');

Many people in this factory function do not regard him as a form of building objects. Part of the reason is semantics: it's not as formal as it was constructed with operator new. A bigger reason is that every time the factory produces an object, it creates a new function showname (), that is, each object has a different version, but in fact they share the same function.
Some people define the ShowName in the factory function, and then point to the method by attributes to avoid the problem:
Copy Code code as follows:

function ShowName () {
alert (this.name);
}
function Createobj (name) {
var tempobj = new Object;
Tempobj.name = name;
Tempobj.showname = ShowName;
return tempobj;
}
var obj1 = createobj (' Obj_one ');
var obj2 = createobj (' Obj_two ');

Unfortunately, this way makes showname () This function look like a method of object.
"Constructor Method"
This approach is to solve the first problem with the factory function above, that is, the problem of no new operator. But the second problem is that it still cannot be solved. Let's take a look.
Copy Code code as follows:

function OBJ (name) {
THIS.name = name;
This.showname = function () {
alert (this.name);
}
}
var obj1 = new Obj (' Obj_one ');
var obj2 = new Obj (' Obj_two ');

The advantage of this is that you do not have to create a new object within the constructor, because the new operator automatically creates an object when it executes, and only through this can you access the object. So we can assign this object directly through this. And no more return, because this points to the returned value that defaults to the constructor.
Also, it's more "formal" to create the object we want with the new keyword.
Unfortunately, it still does not solve the problem of generating method functions repeatedly, as in the case of factory functions.

"Prototype Mode"
In contrast to this approach, there is a big advantage that it solves the problem that the method function is generated multiple times. It leverages the prototype property of the object. We rely on prototypes to override object instances.
Copy Code code as follows:

var Obj = function () {}
Obj.prototype.name = ' me ';
Obj.prototype.showName = function () {
alert (this.name);
}
var obj1 = new OBJ ();
var obj2 = new OBJ ();

We rely on the stereotype to override the constructor, both the property and the method to the newly created object by reference to the stereotype, and therefore only once. Unfortunately, there are two fatal problems in this way:
1. There is no way to write the desired attribute when the object is built, because the stereotype is outside the constructor function, and there is no way to write an attribute value when the object is created by passing arguments. Values can only be overridden after the object has been created.
2. The fatal problem is that when the attribute points to an object, the object is shared by multiple instances. Consider the following code:
Copy Code code as follows:

var Obj = function () {}
Obj.prototype.name = ' me ';
Obj.prototype.flag = new Array (' A ', ' B ');
Obj.prototype.showName = function () {
alert (this.name);
}
var obj1 = new OBJ ();
var obj2 = new OBJ ();
Obj1.flag.push (' C ');
alert (Obj1.flag); A,b,c
alert (Obj2.flag); A,b,c

Yes, when the flag attribute points to an object, the instance obj1 and Obj2 share it, even if we only change the flag attribute of obj1, but its change is visible in the instance obj2.
In the face of this problem, we have to consider whether the "constructor mode" and "prototype mode" should be combined to make them complementary ...

"Constructor and prototype blending"
We let the attribute be created in a constructor way, and the method is created in a prototype way:
Copy Code code as follows:

var Obj = function (name) {
THIS.name = name;
This.flag = new Array (' A ', ' B ');
}
Obj.prototype = {
Showname:function () {
alert (this.name);
}
}
var obj1 = new OBJ ();
var obj2 = new OBJ ();
Obj1.flag.push (' C ');
alert (Obj1.flag); A,b,c
alert (Obj2.flag); A,b

This approach effectively combines the advantages of prototypes and constructors, which are currently used most and have the least side effects.
However, some of the pursuit of perfection is not satisfied, because the visual is not up to their requirements, because the process of creating a method through the prototype will visually make it feel that it is not much like the example of the method (especially for the traditional OOP language developers.) )
So, we can let the prototype move up and let him join the constructor so that the constructor is more visually unified. This sequence of processes can only be accomplished with a single judgment.
Copy Code code as follows:

var Obj = function (name) {
THIS.name = name;
This.flag = new Array (' A ', ' B ');
if (typeof obj._init = = ' undefined ') {
Obj.prototype = {
Showname:function () {
alert (this.name);
}
};
Obj._init = true;
}
}

As above, use _init as a flag to determine if a method has been created for the prototype. If so, it will not be executed. In fact, there is no change in nature, the method is still created through the prototype, the only difference is that this constructor looks "unified".
But there is a problem with the way the dynamic prototype is, and the JavaScript Advanced Program is not being delved into. The first object is created because the prototype is not accessible and built before the object is instantiated. So the first object is inaccessible to the prototype method. This approach also has problems with subclass inheritance.
As for the solution, I will explain it in the next article.

In fact, the use of convenience, the individual feel that there is no need to do this judgment ... Oh ^_^

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.