在下划线中,有一个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]
之间是否存在差异?
答案 0 :(得分:4)
使用git blame显示消息为added in a commit"修复IE不可枚举的属性"。
从那里开始,更多的挖掘表明它是在IE 8及更早版本中修复此错误:IE8 property enumeration of replaced built-in properties (e.g. `toString`)