If you are not familiar with JSON, take a look at this: JSON three-minute course and JSON Entry course.
JSON is mainly used to parse a JSON string into an object and convert an object into a JSON string.
After searching for JSON parsing on the internet, you will find a bunch of articles and Methods. Of course, this article mainly does not discuss JSON parsing, but you can also roughly review it:
First, eval. Eval ('+ jsonstr +'); brackets are added to force expression operations. Otherwise, directly eval ('{}'), for specific reasons, refer to the JS language essence and programming practices.
2. Function
Third, there is another JSON-parsed library, which can be downloaded by yourself
Fourth, in addition to IE6 and 7, modern browsers have basically built-in JSON parser
[Note: Prototype also implements an evaljson method, but it cannot be separated from the above situations]
Example ):
(function(){
var obj = "{\"name\":\"xesam\"}";
console.log('eval:',eval('(' + obj + ')'));
console.log('Function',(new Function('return' + obj))());
console.log('JSON:',JSON.parse(obj));
})();
// Result: {Name: 'xesam '}
Now, the above process is reversed, and an object is encoded as a JSON string. Similarly, if the browser has a native JSON method, there is a method stringify corresponding to parse
(function(){
var obj = {name:'xesam'};
console.log('obj:',JSON.stringify(obj));//'{"name":"xesam"}'
})();
This operation does not have as many methods as parsing, so you need to write it yourself.
Before writing, we will first discuss the possible situation of the target object and convert it into a string.
var object_1 = null;
var object_2 = undefined;
var object_3 = 12;
var object_4 = '12';
var object_5 = true;
var object_6 = [1,2,3];
var object_7 = {name :'xesam'};
var object_8 = {name : function(){}};
First, it is hard to specify that the corresponding 'null', 'undefined ', 'true', and 'false' are returned for null, undefined, true, and false '. Returns the value corresponding to the number directly and the string directly.
The following sections mainly differentiate the array type and function. The main operation is to traverse each item and expand each item in sequence when an array or common object is encountered. Therefore, an initial version can be obtained:
(function(){
function object2Str(object){
if(arguments.length != 0 && typeof object == 'undefined'){
return 'undefined';
}
switch (object) {
case null : return 'null';
case true : return 'true';
case false: return 'false';
}
var type = Object.prototype.toString.call(object);
switch(type){
case '[object Number]' : return String(object);
case '[object String]' : return String(object);
case '[object Array]' : {
var ret = [];
for(var i = 0,len = object.length; i < len; i++){
ret.push(object2Str(object[i]));
}
return '[' + ret.join(',') + ']';
}
case '[object Object]' :{
var ret = [];
for(var key in object){
if(object.hasOwnProperty(key)){
if(typeof object2Str(object[key]) != 'undefined'){
ret.push(String(key) + ':' + object2Str(object[key]));
}
}
}
return '{' + ret.join(',') + '}';
}
}
}
console.log(object2Str(null));
console.log(object2Str(undefined));
console.log(object2Str(true));
console.log(object2Str(12));
console.log(object2Str('34'));
console.log(object2Str({name : function(){}}));
var object = [1,2,3,4,[5,6,7,8,9],6];
console.log(object2Str(object));
var object = {
name:'xesam',
age : 24,
books:{
key_1 : 'book_1',
key_2 : 'book_2'
}
};
console.log(object2Str(object));
})();
Looking at this implementation, {Name: function () {} is not explicitly mentioned, because by default, if (typeof object2str (object [Key])! = 'Undefined.
The basic framework has been obtained, and our implementation also includes undefiend processing. prototype implementation does not have this step. Pay attention to this.
The following are some repairs to continue:
In the preceding example, we ignore the differences between var number_1 = 12 and VAR number_2 = new number (12). We will first fill in the differences between the two.
Therefore, before processing each value, call valueof directly to obtain the original value of the variable. The example above becomes:
(function(){
function object2Str(object){
if(arguments.length != 0 && typeof object == 'undefined'){
return 'undefined';
}
var type = Object.prototype.toString.call(object);
switch (type) {
case '[object Number]' :
case '[object String]' :
case '[object Boolean]':
object = object.valueOf();
}
switch (object) {
case null : return 'null';
case true : return 'true';
case false: return 'false';
}
type = typeof object;
switch(type){
case 'number' : return String(object);
case 'string' : return String(object);
case 'object' : {
var ret = [];
if(Object.prototype.toString.call(object) == '[object Array]'){
for(var i = 0,len = object.length; i < len; i++){
ret.push(object2Str(object[i]));
}
return '[' + ret.join(',') + ']';
}else if(Object.prototype.toString.call(object) == '[object Function]'){
return '{}';
}else{
for(var key in object){
if(object.hasOwnProperty(key)){
if(typeof object2Str(object[key]) != 'undefined'){
ret.push(String(key) + ':' + object2Str(object[key]));
}
}
}
return '{' + ret.join(',') + '}';
}
}
}
}
console.log(object2Str(null));
console.log(object2Str(undefined));
console.log(object2Str(true));
console.log(object2Str(12));
console.log(object2Str('34'));
console.log(object2Str({name : function(){}}));
var object = [1,2,3,4,[5,6,7,8,9],6];
console.log(object2Str(object));
var object = {
name:'xesam',
age : 24,
books:{
key_1 : 'book_1',
key_2 : 'book_2'
}
};
console.log(object2Str(object));
})();
[Note: The above implementation is not escaped ",/, \ and some control operators in prototype, which call string. the inspect method is implemented, but this part is in the string part after it, so for the time being, you can understand it]
Now return to prototype. In prototype, a similar method is called STR [this function starts with an upper case, indicating that it is a local function, and another function starts with type in upper case, these two methods are not made public]
Compared with object2str and STR, apart from the special character escape mentioned above, the STR implementation has two more parameters: Key and stack.
What is the role of this stack? To avoid stack overflow caused by cyclic usage.
For example, I have an object:
VaR OBJ = {Name: This }.
If you call the STR method in prototype, A typeerror is returned. If you call object2str directly, stack overflow is reported. Therefore, this is a necessary check.
Therefore, the final version is:
(function(){
function object2Str(object,stack){
stack = stack || [];
if(arguments.length != 0 && typeof object == 'undefined'){
return 'undefined';
}
var type = Object.prototype.toString.call(object);
switch (type) {
case '[object Number]' :
case '[object String]' :
case '[object Boolean]':
object = object.valueOf();
}
switch (object) {
case null : return 'null';
case true : return 'true';
case false: return 'false';
}
type = typeof object;
switch(type){
case 'number' : return String(object);
case 'string' : return String(object);
case 'object' : {
for (var i = 0, length = stack.length; i < length; i++) {
if (stack[i] === object){
console.log('error');
throw new TypeError();
}
}
stack.push(object);
var ret = [];
if(Object.prototype.toString.call(object) == '[object Array]'){
for(var i = 0,len = object.length; i < len; i++){
ret.push(object2Str(object[i]));
}
ret = '[' + ret.join(',') + ']';
}else{
for(var key in object){
if(object.hasOwnProperty(key)){
if(typeof object2Str(object[key],stack) != 'undefined'){
ret.push(String(key) + ':' + object2Str(object[key],stack));
}
}
}
ret ='{' + ret.join(',') + '}';
}
stack.pop();
return ret;
}
}
}
console.log(object2Str(null));
console.log(object2Str(undefined));
console.log(object2Str(true));
console.log(object2Str(12));
console.log(object2Str('34'));
console.log(object2Str({name : function(){}}));
var object = [1,2,3,4,[5,6,7,8,9],6];
console.log(object2Str(object));
var object = {
name:'xesam',
age : 24,
books:{
key_1 : 'book_1',
key_2 : 'book_2'
}
};
console.log(object2Str(object));
var object = {
name : this
}
console.log(object2Str(object));
})();
In addition, in an object, STR serves tojson, so this call method is specially processed. The parameter format is STR (Key, holder, stack)
Because a keys method and a values method are implemented in prototype objects
for(var key in object){
if(object.hasOwnProperty(key)){
if(typeof object2Str(object[key]) != 'undefined'){
ret.push(String(key) + ':' + object2Str(object[key]));
}
}
}
The keys function is used directly. The specific implementation of prototype is:
var keys = Object.keys(value);
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i], str = Str(key, value, stack);
if (typeof str !== "undefined") {
partial.push(key.inspect(true)+ ':' + str);
}
}
Therefore, the call form of tojson is changed:
function toJSON(value) {
return Str('', { '': value }, []);
}
If we follow the instructions in the example, you can directly
function toJSON(value) {
return object2Str(value, []);
}
After STR is completed, the other method that is used is the inspect method. As the name suggests, the check function can be used for debugging.
One of the simplest implementations:
(function(){
function inspect(object){
return object.toString();
}
})();
Null and undefined do not have the tostring method. By the way, typeof null = 'object', but null does not have the tostring method. Therefore, null cannot be a simple object.
So this discussion has been discussed before and skipped once.
Others are some detection and optimization mechanisms. It is not important.
As for the keys (values) method, it is very easy to copy python, traverse the key (value) of an object, and then load it into an array to return.
The specific implementation of tohtml, ishash, and toquerystring is closely related to the latter, so we will not talk about it here.
For more information, see http://www.cnblogs.com/xesam /]
Address: http://www.cnblogs.com/xesam/archive/2011/12/22/2297781.html