1, JavaScript closure
var add = (function () { var counter = 0; return function () {return counter += 1;} })(); add(); add(); add(); // The counter is 3
Instance resolution:
The variable add specifies the return value of the function self call
2, Why do I need prototype
Method for creating a new object:
1.new Object: var newObj = new Object; newObj.name = "keti"; newObj.color = "red"; newObj.changeColor = function(color){ newObj.color = color; }
This method looks stupid, so we found another method: create it directly with literal, which looks much more elegant:
2.literal var newObj = { name: "keti"; color: "red"; changeColor: function(color){ newObj.color = color; } }
Using literal to common objects seems very good and intuitive. Two curly brackets are an object. It's more clear. But if you want to create a series of objects with similar structure, do you want to write them one by one? As programmers, our idea is to reduce repetition as much as possible, which is the famous DRY(Don't repeat yourself). So we can't tolerate such a stupid thing, so we have a constructor, which is a little similar to a class, but we don't discuss classes here. The constructor is to create a template that does not bind data but only provides a schema. You can generate a new object by filling the relevant data into the template:
3.Constructor function NewObj(name,color){ this.name = name; this.color = color; this.changeColor = function(c){ this.color = c; } }
var newObj1 = new NewObj("keti","red");
In the above code, new is a constructor, and NewObj is the template we have created. Fill in the data and assign it to the variable newObj1, ok. The new object is generated in this way.
It seems that the method of creating objects here is very good, but after careful observation, we also found a new problem: the method of changeColor() is actually the same for all instances, that is, it can be shared, unlike name and color, which need to be bound to each instance. The constructor will copy all its attributes to each instance every time, which causes unnecessary waste; Moreover, when we want to modify this method, we must regenerate all instances to get updates, for example:
function NewObj(name,num){ this.name = name; this.num = num; this.changNum = function(c){ this.num = c; } } var newObj1 = new NewObj("kemi",10); newObj1.changNum(100); newObj1.num; //It's obviously 100 I want to modify it now changNum()This function: function NewObj(name,num){ this.name = name; this.num = num; this.changNum = function(c){ this.num = c*2; } } newObj1.changNum(100); newObj1.num; //It is still 100, which means that this object is not affected by the template we modified
How to solve this problem? There is a prototype object. The attributes and methods in the prototype object are not copied to each instance like the constructor's own attributes, but "references". It can also be understood as providing each instance with a pointer to the prototype object, so that each instance can find the attributes in the prototype object. Obviously, this is a kind of sharing, that is, when you modify the attributes in the prototype, Then all instances sharing this attribute can get this modification. Therefore, the prototype just solves the two problems mentioned above.
function NewObj(name,num){ this.name = name; this.num = num; } NewObj.prototype.changNum = function(c){ this.num = c; } var newObj1 = new NewObj("kemi",10); newObj1.changNum(100); newObj1.num; //It's obviously 100 NewObj.prototype.changNum = function(c){ this.num = c*2; }//Let's revise this method again newObj1.changNum(100); newObj1.num; //It's 200.
Why do you usually write attributes directly in the constructor and add methods through prototype? The differences between these two methods have been shown above: most instance properties are different, such as name, so it is undoubtedly a good scheme to bind directly to instance through this in the constructor, and the methods are usually general. Using prototype can make each instance share the same method instead of copy ing once, It can also realize real-time update.