xcodebuild
xcodebuild

Reputation: 1221

Why "constructor is a special case"?

In underscore, there is a collectNonEnumProps:

var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'
];

function collectNonEnumProps(obj, keys) {
    var nonEnumIdx = nonEnumerableProps.length;
    var constructor = obj.constructor;
    var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto;

    // Constructor is a special case.
    var prop = 'constructor';
    if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop);

    while (nonEnumIdx--) {
        prop = nonEnumerableProps[nonEnumIdx];
        if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
            keys.push(prop);
        }
    }
}

There is a comment say Constrcutor is a special case, then use _.has(obj, prop) && !_.contains(keys, prop) for constructor but prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) for other props which not special.

I had tried use prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) for constrcutor. Then npm run test everything was ok.

var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
    'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString', 'constructor'
];

var collectNonEnumProps = function(obj, keys) {
    var nonEnumIdx = nonEnumerableProps.length;
    var constructor = obj.constructor;
    var proto = _.isFunction(constructor) && constructor.prototype || ObjProto;


    while (nonEnumIdx--) {
        prop = nonEnumerableProps[nonEnumIdx];
        if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) {
            keys.push(prop);
        }
    }
};

So, why underscore treat constrcutor special?

Or, it's there any differences between _.has(obj, prop) and prop in obj && obj[prop] !== proto[prop]?

Upvotes: 4

Views: 75

Answers (1)

Paul
Paul

Reputation: 141829

Using git blame shows that it was added in a commit with the message "Fix IE non-enumerable properties".

From there, a little more digging revealed that it is to fix this bug in IE 8 and earlier: IE8 property enumeration of replaced built-in properties (e.g. `toString`)

Upvotes: 4

Related Questions