Data types for JavaScript
Simple data types
- String
- Number
- Boolean
- function
- Null
- Undefined
Complex data types
- String
- Number
- Boolean
- Function
- Date
- Array
- Regexp
- Object
Various types of deep replication methods:
Let's take a look at the simple type of replication:
//stringvar s1 = ‘abc‘;var s2 = s1;s2 = ‘ccc‘;console.log(s1);//numbervar n1 = 12.1;var n2 = n1;n2 = 7410;console.log(n1);//booleanvar b1 = true;var b2 = b1;b2 = false;console.log(b1);//nullvar nu1 = null;var nu2 = nu1;nu2 = ‘abc‘;console.log(nu1);//undefinedvar u1 = undefined;var u2 = u1;u2 = ‘abc‘;console.log(u1);
From the above code can be seen, simple type, only need to directly assign the value is deep copy. But there is one exception, that is function.
Then look at the deep copy of string, number, Boolean, date:
//Stringvar s1 = new String(‘s1‘);var s2 = new String(s1);console.log(s2);//Numbervar n1 = new Number(‘1‘);var n2 = new Number(n1);console.log(n2);//Booleanvar b1 = new Boolean(1);var b2 = new Boolean(b1);console.log(b2);//Datevar d1 = new Date();var d2 = new Date(d1);console.log(d2);
In addition to the above practices, it is necessary to copy instance properties. So what about the rest of the function, function, regexp, and array as well as the object? These few are more special, we come one by one:
For deep copies of function and function, we can do this in the following ways:
var f1 = new Function(‘a‘, ‘console.log("f1" + a);‘);var f2 = function(b){console.log(‘f2‘ + b);};//通过toString获取源代码(有浏览器兼容问题)var code = f1.toString();//利用eval进行复制var f1_copy = (function(functionCode){ eval(‘var f = ‘ + functionCode); return f;})(code);f1_copy(‘abc‘);//当然f2也可以用同样的方式来复制。
Next, let's take a look at RegExp, which can also be used to perform a copy at the same time as Eval, or in the following ways:
var reg1 = /abc/g;var reg2 = new RegExp(‘abc‘, ‘gmi‘);var reg1_copy = (function(reg){ var pattern = reg.valueOf(); var flags = (pattern.global ? ‘g‘ : ‘‘) + (pattern.ignorecase ? ‘i‘ : ‘‘) + (pattern.multiline ? ‘m‘ : ‘‘); return new RegExp(pattern.source, flags);})(reg1);
Finally, we say a copy of the array, some people can say, directly with slice copy out is, then we come to see, whether really achieve the effect of it?
var o = {name: ‘Jay‘};var arr1 = [o, ‘22‘, 1];var arr2 = arr1.slice(0);arr2[0].name = ‘Arr2‘;console.log(arr1[0].name);
Very short code, directly to the slice abandoned, slice can only guarantee that the array is new, does not mean that the internal elements are deep copy, then how to do? is to iterate over the elements and make a deep copy of each element. The code is as follows:
var o = {name: ‘Jay‘};var arr1 = [o, ‘22‘, 1];var arr2 = [];for(var i = 0, len = arr1.length; i < len; i++){ //注意,deepClone还未实现 arr2.push(deepClone(arr1[i]));}
Above for different types, special code, then how to copy instance properties? The code is as follows:
var o = {p1: ‘1‘, p2: 2, p3: function(){}};var copy = {};for(var p in o){ //注意deepClone还未实现 copy[p] = deepClone(o[p]);}
Note: For complex types, you also need to Copy.constructor = Source.constructor to ensure that the constructors are consistent.
The final deep copy code
With the above analysis and code examples, what is our final code? The detailed code is as follows:
Self-invoking function, defensive programming; (function (window) {' Use strict '; function Getcustomtype (obj) {var type = typeof obj, Resulttype = ' object '; Simple Type if (Type!== ' object ' | | obj = = = null) {Resulttype = ' simple '; } else if (obj instanceof String | | obj instanceof number | | obj instanceof Boolean | | obj instanceof Date) {RESULTT ype = ' complex '; } else if (obj instanceof function) {Resulttype = ' function '; } else if (obj instanceof RegExp) {resulttype = ' RegExp '; } else if (obj instanceof array) {resulttype = ' Array '; } return Resulttype; } function Cloneproperties (dest, source) {dest.constructor = Source.constructor; For (var p in source) {Dest[p] = Deepclone (source[p]); } return dest; } function Clonesimple (obj) {return obj; } function Clonecomplex (obj) {var result = new Obj.constructor (obj); return cloneproperties (Result); } function Clonefunction (obj) {var funcopy = (function (f) {eval (' varabcdefg_$$$$ = ' + obj.tostring ()); return abcdefg_$$$$; }) (obj); Return cloneproperties (funcopy); } function Cloneregexp (obj) {var pattern = obj.valueof (); var flags = (Pattern.global? ' G ': ') + (pattern.ignorecase? ' I ': ') + (pattern.multiline?) ' m ': '); var reg = new RegExp (pattern.source, flags); Return Cloneproperties (REG); } function Clonearray (obj) {var resultarr = []; for (var i = 0, len = obj.length; i < Len; i++) {Resultarr.push (Deepclone (Obj[i])); } for (var p in obj) {if (typeof p = = = ' number ' && p < len) {continue; } Resultarr[p] = Deepclone (obj[p]); } return Resultarr; } function Cloneobject (obj) {var result = {}; Result.constructor = Obj.constructor; For (var p in obj) {result[p] = Deepclone (obj[p]); } return result; } function Deepclone (obj) {var f = undefined; Switch (Getcustomtype (obj)) {case ' simple ': f = clonesimple;Break Case ' complex ': f = clonecomplex; Break Case ' function ': f = clonefunction; Break Case ' regexp ': f = cloneregexp; Break Case ' array ': f = clonearray; Break Case ' object ': f = cloneobject; Break } return F.call (undefined, obj); }//Mount to Window object window.deepclone = Deepclone;}) (window);
Implementation of a deep copy of JavaScript