mardi 22 mars 2016

Is this a bug in RequireJS?

The source code of requirejs contains a mixin function:

    var op = Object.prototype, ostring = op.toString, hasOwn = op.hasOwnProperty;
    function isFunction(it) {
        return ostring.call(it) === '[object Function]';
    }
    function isArray(it) {
        return ostring.call(it) === '[object Array]';
    }
    function hasProp(obj, prop) {
        return hasOwn.call(obj, prop);
    }
    function eachProp(obj, func) {
        var prop;
        for (prop in obj) {
            if (hasProp(obj, prop)) {
                if (func(obj[prop], prop)) {
                    break;
                }
            }
        }
    }
    function mixin(target, source, force, deepStringMixin) {
        if (source) {
            eachProp(source, function (value, prop) {
                if (force || !hasProp(target, prop)) {
                    if (deepStringMixin && typeof value === 'object' && value &&
                        !isArray(value) && !isFunction(value) &&
                        !(value instanceof RegExp)) {

                        if (!target[prop]) {
                            target[prop] = {};
                        }
                        mixin(target[prop], value, force, deepStringMixin);
                    } else {
                        target[prop] = value;
                    }
                }
            });
        }
        return target;
    }

When deepStringMixin is passed true, and target has an inherited prop property whose key also exits in source, and the value is an object. But target does not have it as its own property. In this case,

if (!target[prop]) {
  target[prop] = {};
}

If target has the inherited prop, and it's truthy, the if test fails. In this case, the prop property won't be created as target's own property, the mixin recursive call will modify the inherited prop.

If target has the inherited prop, and the value is true, the if test fails. In this case, the prop property won't be created as target's own property, either. The mixin recursive call will neither modify the inherited prop nor will it create target's own property.

Scenario 1:

var proto = {
  magic: {}
};
var t = Object.create(proto);
var s = {
  magic: {
    name: "xiaoming"
  },
  prop2: "hello"
};

mixin(t, s, false, true);

The inherited magic property will be modified.

Scenario 2:

var proto = {
  magic: true
};
var t = Object.create(proto);
var s = {
  magic: {
    name: "xiaoming"
  },
  prop2: "hello"
};

mixin(t, s, false, true);

The inherited magic property will remain intact, and no property is created on target. The deep mixin fails.


Is this really a bug?




Aucun commentaire:

Enregistrer un commentaire