为什么“构造函数是一个特例”?

时间:2016-05-03 06:08:54

标签: javascript underscore.js

在下划线中,有一个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);
        }
    }
}

有评论说Constrcutor is a special case,然后使用_.has(obj, prop) && !_.contains(keys, prop)作为构造函数,prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop))作为不特殊的其他道具。

我曾尝试将prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop))用于constrcutor。然后npm run test一切正常。

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);
        }
    }
};

那么,为什么underscore对待constrcutor特殊?

或者,_.has(obj, prop)prop in obj && obj[prop] !== proto[prop]之间是否存在差异?

1 个答案:

答案 0 :(得分:4)

使用git blame显示消息为added in a commit"修复IE不可枚举的属性"。

从那里开始,更多的挖掘表明它是在IE 8及更早版本中修复此错误:IE8 property enumeration of replaced built-in properties (e.g. `toString`)