使用unit.js库时克隆对象很奇怪

时间:2014-12-01 17:34:07

标签: javascript unit-testing object

当我使用"must"库时克隆了名为unit.js的属性的简单JSON对象时,我发现了一种奇怪的行为。参见示例:

var test = require("unit.js"); // delete this line and the result will be good

var input = {
    "parameter": "value",
    "must": {
        "parameter_in": "value_in"
    }
};

console.log("Input: " + JSON.stringify(input, undefined, 2));
var result = clone(input);
console.log("Result: " + JSON.stringify(result, undefined, 2)); // no "must" element
console.log("Result (must): " + JSON.stringify(result.must, undefined, 2));

function clone(obj) {
    var copy;

    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;

    // Handle Date
    if (obj instanceof Date) {
        copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
        copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = clone(obj[i]);
        }
        return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
        copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
        }
        return copy;
    }

    throw new Error("Unable to copy obj! Its type isn't supported.");
}

结果:

Input: {
  "parameter": "value",
  "must": {
    "parameter_in": "value_in"
  }
}
Result: {
  "parameter": "value"
}
Result (must): {
  "parameter_in": "value_in"
}

JSON.stringify不会打印must result的{​​{1}}属性,但它位于克隆对象中,因为JSON.stringify适用于result.must 。如果我删除unit.js行,一切正常。 (我用unit.js@0.1.8)

这是什么原因,unit.js是否向Object.prototype添加了什么?无论是什么,它是一种保护我们的应用程序免受这种错误的方法吗?第三方库可能导致此类错误,这一点非常奇怪。

任何帮助将不胜感激!

Ps。:我使用了How do I correctly clone a JavaScript object?中建议的克隆功能,但它与lodash的cloneDeep方法也是一样的。

更新

我已经尝试了更多查询:在for in上使用inhasOwnPropertyresult

console.log("\"must\" is in: " + ('must' in result));
console.log("\"must\" is with hasOwnProperty: " + result.hasOwnProperty("must"));
console.log("In properties:");
for (var property in result){
    console.log("\tproperty: " + property);
}

unit.js的结果:

"must" is in: true
"must" is with hasOwnProperty: true
In properties:
        property: parameter

因此must属性不会仅出现在for in循环中。

1 个答案:

答案 0 :(得分:1)

我在unit.js的github page上问过它,感谢Nicolas Talle我得到了正确答案。

总结一下,因为must被MustJS添加为非可枚举属性(与ShouldJS的should相同)。我们可以通过添加:

来摆脱这种情况
delete Object.prototype.must;
delete Object.prototype.should;

有关详细答案,请参阅问题:https://github.com/unitjs/unit.js/issues/6

Unit.js的文档也根据这个扩展:http://unitjs.com/guide/must-js.html