📜 ⬆️ ⬇️

DeepClone javascript tweet

Good day!

I don’t know if anyone would be interested, but he built a miracle today: DeepClone, loaded up to 140 bytes.
If someone has already done this and post, please poke your nose. I found only shallow copies in the tweet format. Well, I do not exclude that any applied hack is in the list of prohibited drugs , and for its use terrible punishment rely :)

Among the shortcomings, everything is the same as that of cloning using the extend function of jQuery: it does not eat standard objects of the types Boolean, String, Date, ignores prototype and constructor and hangs on the rings.
Dignity is one and, for the most part, purely aesthetic - size.
')
Tested in Firefox, Chromium, Opera, IE8 and in the default android browser.

Under the cut - the code and a short story about how it works.



To begin with, the readable version (called dup because otherwise 140 is not compressed byte):
function dup(o) { // "string", number, boolean if(typeof(o) != "object") { return o; } // null if(!o) { return o; // null } var r = (o instanceof Array) ? [] : {}; for(var i in o) { if(o.hasOwnProperty(i)) { r[i] = dup(o[i]); } } return r; } 


What's going on here:

If the object is simple (string, number, boolean), simply return it, then we check that the object is not null (typeof (null) is also == "object"). Now we create the result (an array or an object) and run through the properties, cloning them recursively.

In general, everything is simple. Now almost 300 bytes must be pressed twice.

We recall some things that will help us:
- typeof is an operator, and it does not need brackets;
- y?: The priority is the lowest, so that the brackets on the left again can be omitted;
- null && {} is null, and obj && {} is obj;
- for (var i in null) passes without error, without doing any iteration;
- The function parameters are also variables, but it is not necessary to pass them all. This will help us save 4 bytes on the word var with a space.

Based on this, we get:
 function dup(o,i,r) { if(typeof o != "object") return o; r = o instanceof Array ? [] : o&&{}; for(i in o) if(o.hasOwnProperty(i)) r[i] = dup(o[i]); return r } 


Well, or in one line (139 letters):
 function dup(o,i,r){if(typeof o!="object")return o;r=o instanceof Array?[]:o&&{};for(i in o)if(o.hasOwnProperty(i))r[i]=dup(o[i]);return r} 

If you increase the allowable size to 150 characters, then you can add reference handling to yourself (not completely resolving the rings, of course, but at least something):
 r[i] = (o[i] === o) ? r : dup(o[i]); 

Or:
 function dup(o,i,r){if(typeof o!="object")return o;r=o instanceof Array?[]:o&&{};for(i in o)if(o.hasOwnProperty(i))r[i]=o[i]===o?r:dup(o[i]);return r} 


Demo: pastehtml.com/view/buikhdvfe.html (to see without the pastehtml wrapper, replace the word "view" in the link with "raw")

UPD:
Thanks to TheShock, the function is still a bit thinner!
His options are:
 function dup(o,i,r) { r=o; if(r && typeof o == "object") { r = o instanceof Array ? [] : {}; for(i in o) if(o.hasOwnProperty(i)) r[i] = dup(o[i]); } return r } // 135 function dup(o,i,r){r=o;if(r&&typeof o=="object"){r=o instanceof Array?[]:{};for(i in o)if(o.hasOwnProperty(i))r[i]=dup(o[i])}return r} //   ie8, 133 : function dup(o,i,r){r=o;if(r&&typeof o=="object"){r=Array.isArray(o)?[]:{};for(i in o)if(o.hasOwnProperty(i))r[i]=dup(o[i])}return r} 

There was also an additional offer from mark_ablov as another save byte, eliminating if:
 o.hasOwnProperty(i)?r[i]=dup(o[i]):1 


UPD 2:
And the final development of the idea is again from TheShock :
 function c(o,i,r){if(o&&typeof o=="object"){r=o instanceof Array?[]:{};for(i in o)o.hasOwnProperty(i)?r[i]=o[i]===o?r:c(o[i]):0}return r||o} 

Exactly 140 bytes of pure win'a, and working under IE8, and with the minimum check of rings!
Cheers, comrades!

Gist: gist.github.com/2369704
Updated demo: pastehtml.com/view/buiv8lzka.html

UPD 3.4: ultimate weapon
For real use, I made another version that does not fit (to put it mildly) into a tweet, but it works with dates and object wrappers, as well as completely resolving any cycles and internal links. Single-line version is 328 bytes.
And I realized that I was a rare eccentric, because I had completely forgotten about the problems with multi-frame and instanceof. Well, in the combat version, and this is also now decided.
Gist here: gist.github.com/0d3e6ce689e76105f3ef
Demo here: pastehtml.com/view/bumpwvs4q.html

Source: https://habr.com/ru/post/141961/


All Articles