Elegant encapsulation or efficiency of execution? This is a paradox.
Elegantly packaged programs look so wonderful: Each attribute is hidden behind an object, and what you see is what the object lets you see, and as to how it operates, it doesn't have to worry you.
The efficiency of execution is another matter. It's like the difference between C and object-oriented C + +: C + + is elegant, but execution efficiency, whether it is compiled binary code or run-time memory footprint, than the simple C language more than a cut.
This problem is more important in scripting languages because JavaScript is simply an interpretive language, and interpreting language is much less efficient than compiling languages.
1. Elegant Packaging
Let's take a look at the variable encapsulation first. The variables here are not just attributes, but functions as well.
As we've already said, there's no such concept in JavaScript, it's a graceful realization that we take advantage of variable scopes and closures "clever simulations". Or warm up the previous code:
function Person() {
var id;
var showId = function() {
alert("My id is " + id);
}
this.getId = function() {
return id;
}
this.setId = function(newId) {
id = newId;
}
}
var p = new Person();
p.setId(1000);
alert(p.id); // undefined
// p.showId(); error: function not defined
var p2 = new Person();
alert(p.getId == p2.getId); // false
We implemented the private variables gracefully-albeit by opportunistic implementations. But what's wrong with this piece of code? Why are the functions of two objects different?
Think about it, we use the scope of variables to simulate a private variable, with a closure to simulate the public variable, then, that is, in fact, each created object will have a copy of the same code! Not only that ID, but even those showid, getId and other functions will be created many times. Note that it's not as weird to think that JavaScript functions are objects. But there is no doubt that this is a waste: Each variable is different from its own data field, the function code is the same, because we are doing the same operation. Other languages generally do not experience this problem because the concepts of functions and objects in those languages are different, like Java, where each object's approach actually points to a copy of the same code, not every object has its own copy of the code.
2. To see efficiency
That package, though elegant, is wasteful. The good news is that JavaScript is a flexible language, so we immediately think that it's okay to point the pointer to another function?
function show() {
alert("I'm a person.");
}
function Person() {
this.show = show;
}
var p1 = new Person();
var p2 = new Person();
alert(p1.show == p2.show); // true
This is a good way to solve the problem we had before: different objects share a piece of code. But while this implementation is efficient, it is not elegant-if I have many classes, wouldn't there be many global functions?
Fortunately, there is another mechanism in JavaScript: prototype. Do you remember this prototype? Each object maintains a prototype property that is shared by the prototype property of the object. So, we can put the definition of function into prototype, so that different objects do not share a copy of the code? This is true:
function Person() {
}
Person.prototype.show = function() {
alert("I'm a person.");
}
var p1 = new Person();
var p2 = new Person();
alert(p1.show == p2.show); // true
However, this split definition looks awkward, so why not write the definition of the function into the class definition?
function Person() {
Person.prototype.show = function() {
alert("I'm a person.");
}
}
var p1 = new Person();
var p2 = new Person();
alert(p1.show == p2.show); // true
In fact, this type of writing is no different from the one above: the only difference is that the code position is different. This is just a "look sweet" grammatical sugar, there is no substantial difference.
Initially, Microsoft's. Net AJAX framework used the previous mechanism to simulate private variables and functions, which is very similar to C #, and is elegant. However, in terms of efficiency, Microsoft later changed it to the definition of the prototype. Although this approach is less elegant, it is efficient.
In JavaScript, there is a contradiction between the elegance of this encapsulation and the efficiency of execution. Now our best solution is to define the data within the class, and the function is defined in the prototype attribute of the class.
Source: http://devbean.blog.51cto.com/448512/174940