Methods and ideas of JavaScript simulation class mechanism and private variables

Source: Internet
Author: User

When using some Javascript frameworks, you may see similar code
Copy codeThe Code is as follows:
Var MyClass = new Class ({
Initialize: function (param ,...){
This. param = param;
...
},
Func1: function (...){
...
}
});
Var myObj = new MyClass (param );
MyObj. func1 (...);

This is a typical object-oriented class mechanism application, which is clearer and more natural than the native Javascript class mechanism. Besides, the inheritance of classes is convenient. So how is this implemented?
As we all know, in Javascript, you can use a function as the constructor to create an object. The above code can be simply written:
Copy codeThe Code is as follows:
Function MyClass (param ){
This. param = param;
This. func1 = function (..){
...
};
}
Var myObj = new MyClass (param );
MyObj. func1 ();

In fact, it is quite simple and easy to understand. However, if you want to build a large Javascript class library, it may be confusing. From a bunch of code, you need to find out which classes, functions, and class methods are required, what are class attributes is a pain point.
Of course, they are not to be compared here, but just curious about the implementation method of new Class.
In the above Code, the use of statements such as new MyClass () means that MyClass must be a function and new Class needs to return a function object. It can be seen from the literal meaning that, the initialize function is used as a constructor. Therefore, initialize must be used in the function returned by new Class to initialize the object. Based on this analysis, the following code can be obtained:
Copy codeThe Code is as follows:
Function Class (argu ){
Return function (){
Var init = argu ['initialize'] | function () {}; // if no constructor initialize is available, use an empty function as the default constructor.
For (var p in argu ){
This [p] = argu [p];
}
Init. apply (this, arguments); // use this of the current function to replace the original this of initialize.
}
}

The above code is not rigorous enough, but it is enough to explain the problem. Note the init. the apply (this, arguments) clause contains several variables. One is this, which is the default this in initialize and has been replaced by this of the returned anonymous function, the anonymous function is the constructor of the custom Class created through the new Class. The other is arguments, which refers to the parameters of anonymous functions, that is, param in new MyClass (param) above.
The conversion of this is a little dizzy. Is there a simpler way? See the following code:
Copy codeThe Code is as follows:
Function Class (argu ){
Var obj = argu ['initialize'] | function (){};
For (var p in argu ){
Obj. prototype [p] = argu [p]; // note that prototype is used here.
}
Return obj; // returns a function.
}

Haha, I feel a lot straightforward.
This completes the construction of a simple class mechanism. Through this mechanism, you can create class constructors, methods, and attributes, but these are obviously public. So how to implement private variables and methods?
We know that private variables of Javascript classes can be implemented through the closure mechanism. However, after using the new Class ({...}) method for conversion, it is obviously difficult to form an effective closure. How can this problem be bypassed?
Javascript provides two methods: eval () and toString () of the function object. The former is more common, while the latter can be used to obtain the specific code of the function. Using these two methods, you can easily simulate the private variables of the class:
Copy codeThe Code is as follows:
Function Class (argu ){
Var _ = argu ['private'] | | {};
Eval ('var obj = '+ (argu ['initialize'] | function () {}). toString ());
For (var p in argu ){
If (p = 'initialize' | p = 'private ')
Continue;
If (typeof argu [p] = 'function ')
Eval ('obj. prototype [p] = '+ argu [p]. toString ());
Else
Obj. prototype [p] = argu [p];
}
Return obj;
}

The toString () method of the function object is used to extract the code of the function and run the code using the eval method. In this way, an effective closure range can be constructed to implement the private mechanism. We can use the following applications:
Copy codeThe Code is as follows:
Var Person = new Class ({
Private :{
Height: 160,
Weight: 50
},
Initialize: function (name, height, weight ){
This. name = name;
_. Height = height | _. height;
_. Weight = weight | _. weight;
},
Show: function (){
Alert ('name: '+ this. Name +'/nheight: '+ _. height +'/nweight: '+ _. weight );
}
});
Var my = new Person ("Zh ");
My. show ();

It does not look good, but in actual application, it is not very useful. It is mainly about efficiency. Compared with the common implementation method, it takes about four more times. In the construction of large class libraries, this is intolerable. In small applications, the following code is simpler and more straightforward:
Copy codeThe Code is as follows:
Function MyClass (param ){
Var privateVar = ...;
This. param = param;
This. func = function (){
Alert (privateVar );
};
}

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.