Different methods in JavaScript to do deep clone for plain object without libraries

1, use JSON.parse and JSON.stringify, but it has many issues, major one is can’t handle Date type.

var cloned = JSON.parse(JSON.stringify(objectToClone));

2, refer to this, mainly ideas is loop the properties one by one, and go into children, also need to handle ‘Function’, ‘Symbol’, ‘WeakSet’, etc. all possible data types in JavaScript :


function clone(obj) {
    if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
        return obj;

    if (obj instanceof Date)
        var temp = new obj.constructor(); //or new Date(obj);
        var temp = obj.constructor();

    for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            obj['isActiveClone'] = null;
            temp[key] = clone(obj[key]);
            delete obj['isActiveClone'];
    return temp;

also there are more examples could refer to, for example this version needs ES6 supports https://stackoverflow.com/questions/40291987/javascript-deep-clone-object-with-circular-references

function deepClone(obj, hash = new WeakMap()) {
    // Do not try to clone primitives or functions
    if (Object(obj) !== obj || obj instanceof Function) return obj;
    if (hash.has(obj)) return hash.get(obj); // Cyclic reference
    try { // Try to run constructor (without arguments, as we don't know them)
        var result = new obj.constructor();
    } catch(e) { // Constructor failed, create object without running the constructor
        result = Object.create(Object.getPrototypeOf(obj));
    // Optional: support for some standard constructors (extend as desired)
    if (obj instanceof Map)
        Array.from(obj, ([key, val]) => result.set(deepClone(key, hash), 
                                                   deepClone(val, hash)) );
    else if (obj instanceof Set)
        Array.from(obj, (key) => result.add(deepClone(key, hash)) );
    // Register in hash    
    hash.set(obj, result);
    // Clone and assign enumerable own properties recursively
    return Object.assign(result, ...Object.keys(obj).map (
        key => ({ [key]: deepClone(obj[key], hash) }) ));

Anyway, I recommend to use JavaScript library ‘clone‘ for the deep clone, it could handle circular reference correctly.

If you need to create more complex feature to re-create (serialization) new instance from source object or JSON string (and use TypeScript), I prefer to use this https://github.com/typestack/class-transformer The ‘class-transformer’ doesn’t force you to describe the class with decorator (of course you could do it, and have to if you need rich features), it is good point I prefer to.


git checkout -b new-feature
git status
git add .
git commit -m “message for this time”

git push -u origin new-feature

// create pull request on stash web

// delete the new-feature
git branch -D new-feature

// for very large repo
git clone -b –depth=1

// if local is behind
git pull origin master



旧的浏览器只能支持ES5是一个极为糟糕的痛点,不得不通过各种办法翻译代码到ES5。我的选型就是TS+Babel+Webpack,基本上也是前端的标配了。比较坑的是这里面配置文件的设定要花一些时间,消耗了我不少脑细胞和时间去搜索和尝试,感兴趣的可以留言交流具体的问题。有一个小窍门,是参考其它框架的工程实践,比如vue的https://cli.vuejs.org/zh/guide/browser-compatibility.html 这里面就列出了一些可以借鉴的要点,包括参考vue-cli的源代码,也可以借鉴(copy)那些babel插件可以用,如何配置config文件等等。

关于production环境发布部署,可以参考这篇文章https://philipwalton.com/articles/deploying-es2015-code-in-production-today/ 主要是利用浏览器对于“module”关键字识别与否,条件加载转译到ES5的或者直接就是ES6的代码。现在还没有用在当前项目,不过以后如果遇到性能问题的话,就要考虑这个点了。