Javascript does not have keywords for private and public access rights settings, but you can simulate the same result through certain techniques.
First, let’s look at the following line of code:
var i = (1, 2, 3, 4 , 5);
The final result of variable i is 5.
This is the result of the comma operator, which means that the last value is returned. The parentheses change the priority of this line of code, otherwise var i = 1, 2, 3, 4, 5; will report an error of missing identifier.
var i = (1, 2, 3, 4, function(){ return 5 * 5;});
The final result of variable i is a function, returning the result 25.
This is the flexibility of Javascript, which can assign any type without having to declare it in advance. Now we can make the following call:
i ();
alert( i() );
to get a method call that returns 25.
We continue, the variable i gets the reference of the function through the assignment operator, In other words, the reference to the last result returned after the operation of the parentheses on the right side of the equal sign is still there. Although we cannot display the call, it does exist. What if it is called without a reference to a variable?
(1, 2, 3, 4, function(){ alert(5 * 5);})()
After the above code is executed, a message box pops up, displaying 25.
For the convenience of display, I The function in the previous example was changed to a pop-up message box.
Two pairs of parentheses () (); The first pair indicates that a result is returned. If the result is a function, the call is made by the second pair of parentheses.
That is, the reference to the anonymous function occurs through the previous pair of brackets for reference below. This is the call to the anonymous function.
For more information on the use of anonymous functions, please refer to the reference link at the end of the article.
The reason why closures are generated is because of the different scopes. The child scope refers to the variables of the parent scope and returns to the child scope. Logically speaking, the parent scope should be destroyed after execution, but the child scope It has always existed and has a reference to the parent scope, so it has been retained.
Look at the following code
function parent() {
var a = 1;
function child(){
var b = 2;
alert(a) ;
alert(b);
}
}
The parent function parent contains a child function, and in the child function there is a reference to the a variable in the parent function Reference (output its value).
Let’s let the parent function return its declared child function after execution
function parent() {
var a = 1;
function child(){
var b = 2;
alert(a);
alert(b);
}
return child;
}
var t = parent();
t();
on line 10 , we executed the parent function and returned the function child declared inside the function. At this time, the variable t holds a reference to the returned object (which is an executable function at this time), and we called it in 11 lines of code. The results are output 1 and 2 respectively.
Note that the output 2 is because we declared a variable in the sub-function body, and the output 1 is because we did not define the variable a correspondingly in the function body, but an exchange occurred. The reference to the variable in the parent function, that is to say, the variable in the parent scope is referenced.
At this time, the output can be completed, which means that the variable a still exists. But we cannot directly reference it (such as parent .a), because the function has been executed and there is no corresponding reference, we can only access it through the reference of the returned sub-function.
What if I declare other variables in the parent function? Result It’s the same, the sub-function can be accessed, but if the sub-function does not return the corresponding reference, we cannot access it from the outside at all. This forms a closure.
What can a closure do? What should you do if you have a variable that you don’t want the outside world to modify at will? Then use a closure.
myObj = {}; //Declare a global variable, which is a property of a window object (window.myObj)
(function(){
var i = 4;
myObj = { //Reference global variables and assign values to them
getI : function() { //get method, a function
return i;
},
setI : function( val) { //set method, setting limit value
if(val > 100) {
alert("i connt > 100");
return;
}
i = val;
}
}
})(); //The call of the anonymous function is also a function, so it is used as a sub-scope and is destroyed after execution to avoid code pollution
myObj.setI(5); //Success
myObj.setI(101); //Failure
alert(myObj.getI());
alert(myObj.i); //Error, There is no such attribute
So far we have simply implemented public access rights and private access rights (that is, giving you what you want, and not giving you what you don’t want to give you)
In In the page, we usually use the document.cookie attribute to access it. Assigning a new value to it will create a new Cookie. A Cookie usually has five attributes: value (stored value), date (time in UTC format, what does it represent) Time expiration, domain (domain, cookie owner), Path (subdirectory).
In normal development, if you only use the document.cookie attribute to access, it will be very troublesome, because you can only assign characters to it String, and the string must be cut after reading to obtain the value of the specified variable name. When document.cookie is read, all assigned values are returned, excluding information such as expiration time, domain, etc. It can be set independently again.
The code is attached below, all encapsulated into the Cookie global object, exposing several methods.
Get: Put back all the specified cookie strings.
Set: Set the cookie string .
Clear: Clear all cookie objects.
GetDayTime: Get the Date object specifying the val day from now.
Write: Write cookies. Overloaded. See code for details.
Query: Query cookies. Overloaded. See code for details.
Update: Modify cookies.
Delete: Delete cookies.
Code 1-7
Cookie = {};
/*
* The setTime method of the Date object is to set the number of milliseconds since 1970-01-01, set it in the object, and return the date since then The number of milliseconds instead of the original object.
* If the cookie does not set the expires attribute, or the expires time is less than the local time, it will expire on the next browse.
* The document.cookie object returns all values String form, does not include expires or others.
*
*/
(function() {
var nDay = 24 * 60 * 60 * 1000;
var isString = function(v ) {
return typeof v === "string";
}
var isArray = function(v) {
return Object.prototype.toString.apply(v) == "[object Array ]";
}
var isObject = function(v) {
return v && typeof v == "object";
}
var isDate = function(v) {
return Object.prototype.toString.apply(v) == "[object Date]";
}
var getTime = function() {
return new Date().getTime();
}
var trim = function(val) {
return (val || "").replace(/^s |s $/g, "");
}
var tryEval = function (val) {
var Obj, e;
try {
Obj = eval(val);
} catch (e) {
Obj = val;
}
return Obj;
}
var ObjectToString = function(o) {
var tstr = "{";
for (var v in o) {
if (isArray(o[v] )) {
tstr = v ":" ArrayToString(o[v]) ",";
} else if (isObject(o[v])) {
tstr = v ":" ObjectToString( o[v]) ",";
} else if (isString(o[v])) {
tstr = v ":"" o[v].toString() "",";
} else {
tstr = v ":" o[v].toString() ",";
}
}
return tstr.slice(0, -1) "}";
}
var ArrayToString = function(o) {
var tstr = "[";
for (var v in o) {
if (isArray(o[v])) {
tstr = ArrayToString(o[v]) ",";
} else if (isObject(o[v])) {
tstr = ObjectToString(o[v]) ",";
} else {
tstr = o[v].toString() ",";
}
}
return tstr.slice(0, -1) "]"; ;
}
Cookie = {
Get: function() {
return document.cookie;
},
Set: function(val) {
document.cookie = val;
},
Clear: function() {
var temp = this.Query();
var o;
for (o in temp) {
this.Delete(o);
}
},
GetDayTime: function(val) {
var texpires = new Date();
texpires.setTime(texpires.getTime() val * nDay);
return texpires;
},
Write: function() {
/*
* Cookie.Write(Object); Write object, name is main;
* Cookie.Write(varname , Object); varname: variable name, Object: write object;
* Cookie.Write(Object, Date); Object: write object, Date: expiration time;
* Cookie.Write(varname, Object , Date); varname: variable name, Object: write object, Date: expiration time;
* Cookie.Write(varname, Object, Date, Domain, Path); varname: variable name, Object: write object, Date: expiration time, Domain: domain, Path: subdirectory;
*/
if (arguments.length == 1) {
var tvalue = arguments[0];
var tstr = " ";
var texpires = new Date(); texpires.setTime(texpires.getTime() 1 * nDay);
if (isArray(tvalue)) {
tstr = ArrayToString(tvalue);
} else if (isObject(tvalue)) {
tstr = ObjectToString(tvalue);
} else {
tstr = tvalue.toString();
}
tstr = "main= " escape(tstr) ";expires=" texpires.toGMTString() ";";
} else if (arguments.length == 2) {
var tname, tvalue, texpires, tstr = "";
if (isDate(arguments[1])) {
tname = "main";
tvalue = arguments[0];
texpires = arguments[1];
} else {
tname = arguments[0];
tvalue = arguments[1];
texpires = new Date(); texpires.setTime(texpires.getTime() 1 * nDay);
}
if (isArray(tvalue)) {
tstr = ArrayToString(tvalue);
} else if (isObject(tvalue)) {
tstr = ObjectToString(tvalue);
} else {
tstr = tvalue.toString();
}
tstr = tname "=" escape(tvalue) ";expires=" texpires.toGMTString() ";";
} else if (arguments.length == 3) {
var tname = arguments[0], tvalue = arguments[1], texpires = arguments[2], tstr = "";
if (isArray(tvalue)) {
tstr = ArrayToString (tvalue);
} else if (isObject(tvalue)) {
tstr = ObjectToString(tvalue);
} else {
tstr = tvalue.toString();
}
tstr = tname "=" escape(tvalue) ";expires=" texpires.toGMTString() ";";
} else if (arguments.length == 5) {
var tname = arguments[0] , tvalue = arguments[1], texpires = arguments[2], tdomain = arguments[3], tpath = arguments[4], tstr = "";
if (isArray(tvalue)) {
tstr = ArrayToString(tvalue);
} else if (isObject(tvalue)) {
tstr = ObjectToString(tvalue);
} else {
tstr = tvalue.toString();
}
tstr = tname "=" escape(tvalue) ";expires=" texpires.toGMTString() ";domain=" tdomain ";path=" tpath ";";
}
alert(tstr);
this.Set(tstr);
},
Query: function() {
/*
* Cookie.Query(); Returns an Object composed of all Cookie values;
* Cookie.Query(string); Returns an Object with the specified name; If it fails, it returns undefined;
* Cookie.Query(string, Object); Writes an Object with the specified name for the specified object and returns; If it fails, it returns undefined;
*/
var tname = tvalue = " ", tright = -1;
var tstr = this.Get();
var tObj = {};
if (arguments.length == 0) {
var i = 0;
do {
tname = trim(tstr.slice(i, tstr.indexOf("=", i)));
tright = tstr.indexOf(";", i);
if (tright == -1) {
tvalue = unescape(tstr.slice(tstr.indexOf("=", i) 1, tstr.length));
} else {
tvalue = unescape( tstr.slice(tstr.indexOf("=", i) 1, tright));
}
tObj[tname] = tryEval(tvalue);
i = tstr.indexOf(";", i) == -1 ? -1 : tstr.indexOf(";", i) 1;
} while (i != -1);
} else {
tname = arguments[0] ;
if (tstr.indexOf(tname) == -1) return undefined;
var i = tstr.indexOf(tname);
tname = trim(tstr.slice(i, tstr.indexOf( "=", i)));
tright = tstr.indexOf(";", tstr.indexOf(tname)) == -1 ? tstr.length : tstr.indexOf(";", tstr.indexOf( tname));
tvalue = unescape(tstr.slice(tstr.indexOf(tname) tname.length 1, tright));
if (arguments.length == 1) {
tObj = tryEval( tvalue);
} else if (arguments.length == 2) {
tObj = arguments[1];
tObj[tname] = tryEval(tvalue);
}
}
return tObj;
},
Update: function() {
return this.Write.apply(this, arguments);
},
Delete: function() {
if (arguments.length == 1) {
var varname = arguments[0];
if (this.Query(varname)) {
this.Update(varname, "", new Date( 1970, 01, 01));
}
}
}
}
There is an execution of eval from string to object, and from The Object or Array object obtains the corresponding function function in the form of a string, simulating some JSON operations. Of course, it cannot store all JavaScript objects, only a part of them are satisfied, and I feel it is enough.
My personal understanding is limited, please give me some advice.
Javascript’s anonymous function:
http://dancewithnet.com/2008/05/07/javascript-anonymous-function/ Javascript closure:
http://www.cn-cuckoo.com/wordpress/wp-content/uploads/2007/08/JavaScriptClosures.htmlCookie File format:
http://www.cnblogs.com/sephil/archive/2008/05/06/cookiefmt.html