Skip to content

Instantly share code, notes, and snippets.

@addyosmani
Forked from 140bytes/LICENSE.txt
Created August 10, 2011 13:39
Show Gist options
  • Save addyosmani/1136817 to your computer and use it in GitHub Desktop.
Save addyosmani/1136817 to your computer and use it in GitHub Desktop.
140byt.es -- objectClone

A quick object-cloning routine in 139 bytes.

/*
* objectClone.js (c) Addy Osmani, 2011.
* Do whatever license.
* Thanks to gf3 and ben_alman for tips that helped improve.
*/
function objectClone(q) {
/*determine if the object is an instance of a known object type (array).if an array, instantiate n as an array*/
var n = (q instanceof Array) ? [] : {},
i;
/*iterate through the input*/
for (i in q) {
/*Object.prototype.toString is a ref to Object.prototype so the results [object Object] will result despite argument supplied. call() however sets toString's 'this' keyword as a ref to the passed input (eg. [object Array]) allowing us to accurately handle different types of input*/
if (Object.prototype.toString.call({}) == Object.prototype.toString.call(q[i])) {
/*if an object, set n to a clone of q[i]*/
n[i] = objectClone(q[i]);
/*otherwise, simply map n[i] to q[i] (eg. for arrays)*/
} else n[i] = q[i]
}
return n;
};
function c(a){var b=a instanceof Array?[]:{},d,e=Object.prototype.toString;for(d in a)b[d]=e.call({})==e.call(a[d])?c(a[d]):a[d];return b}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "objectClone",
"description": "A compact object cloning routine.",
"keywords": [
"object",
"clone",
"cloning"
]
}
<!DOCTYPE html>
<title>Foo</title>
<script>
function c(a){var b=a instanceof Array?[]:{},d,e=Object.prototype.toString;for(d in a)b[d]=e.call({})==e.call(a[d])?c(a[d]):a[d];return b}
/*test cloning*/
var obj = { omg: 'wow', sexypants : 'mikeyface', tester:function(){ console.log('ZOMGAH');}},
test = c(obj);
console.log(obj);
console.log(test);
/*test direct assignment, followed by cloning*/
test.p = 'lalalalalala';
test.magic = function(){
console.log('magicalness');
}
test.tester();
console.log(test);
/*test passing arrays through the cloner*/
var testArray = ['beans','beans','the','magical','fruit'],
testObj = c(testArray);
console.log(testArray);
console.log(testObj);
</script>
@jed
Copy link

jed commented Aug 12, 2011

nice work, addy! would you mind replacing or removing the old README?

also, wouldn't

for(d in a)b[d]=/O/.test(Object.prototype.toString.call(a[d]))?

be just as reliable as

e=Object.prototype.toString;for(d in a)b[d]=e.call({})==e.call(a[d])?

?

@jed
Copy link

jed commented Aug 12, 2011

alternatively, if you're going to cache Object.prototype.toString, why not use that instead of the less-reliable instanceof to suss out an array?

@addyosmani
Copy link
Author

@jed you're absolutely right. Let me play around with the alternatives just to make sure they're able to pass the same basic tests at the end. I'll edit that readme right away. Cheers!

@jed
Copy link

jed commented Aug 12, 2011

just noodling, but i was also wondering about an approach that piggybacks on JSON:

function(a){return JSON.parse(JSON.stringify(a))}

perhaps there's enough space in there to handle functions and undefineds too.

@sebastien-p
Copy link

I think you can shorten Object.prototype.toString to {}.toString.

@atk
Copy link

atk commented Aug 12, 2011

How about this one?

function c(a,b,c){b={};for(c in''+a!==a&&a)b[c]=c(a[c]);return typeof a!='object'?a:a instanceof Array?a.slice():b}

Does not work to the fullest for html nodes, otherwise it's fine - maybe we could utilize a clone method if available...

@jed
Copy link

jed commented Aug 13, 2011

i guess i'm just not clear on what a deep clone should be: should the source and target contain any objects in common?

primitives are easy, and objects are less easy, but functions? you can't really clone a function reliably.

@atk
Copy link

atk commented Aug 13, 2011

Function(func+'') - does not work for native functions.

@jed
Copy link

jed commented Aug 13, 2011

sure, so what is a cloned function? i guess in a pure sense it would be a proxy, but that would kill any hopes of it fitting in 140 bytes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment