We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
var hasEnumBug = !{ toString: null }.propertyIsEnumerable('toString') var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; // 不能用for... in 遍历的 key 集合 var collectNonEnumProps = function (obj, keys) { var nonEnumIdx = nonEnumerableProps.length; var constructor = obj.constructor; // 对象的原型如果被重写,则 proto 为 Object.prototype // 反之,则为 obj.constructor.prototype var proto = _.isFunction(constructor) && constructor.prototype || ObjProto // 如果obj 有 constructor 这个key // 并且没有存在数组中,就存入数组 var prop = 'constructor' if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop) while (nonEnumIdx--) { prop = nonEnumerableProps[nonEnumIdx] // prop 在对象里面,并且与Object原型上的不是同一个引用,且不包含在keys 中 if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { keys.push(prop) } } } // 取出对象的所有属性名 _.allKeys = function (obj) { if (!_.isObject(obj)) return [] // 不是对象,直接返回空数组 var keys = [] for (var key in obj) keys.push(key) // 处理 ie < 9 以下的情况 if (hasEnumBug) collectNonEnumProps(obj, keys) return keys }
上面这段代码中,除了一般的使用 for...in 来取出属性名,后面还有一步判断是否有 可枚举的bug 情况,主要针对,ie<9下,for...in 的问题。不过我在 mdn 上查到 for...in在 ie6 下都支持,所以可能之前编写这个库时 for...in 在ie<9下都不支持
for...in
不过阅读这段代码还是能收获不少
首先
var hasEnumBug = !{ toString: null }.propertyIsEnumerable('toString')
在 ie<9 下,{ toString: null }.propertyIsEnumerable('toString') 会返回 false,因此可以用此来判断是否是 ie<9 的浏览器
{ toString: null }.propertyIsEnumerable('toString')
false
注:现在ie 下的情况:
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; 这是一些不可枚举的属性,除了 constructor:
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
constructor
var proto = _.isFunction(constructor) && constructor.prototype || ObjProto 这里上面代码里面注释了一些,不过还要说的一点是, _.isFunction(constructor) && constructor.prototype 排除了 对象的 constrcutor 是直接量的问题,并且排除了 var a = {}; a.__proto__ = null 的情况,如果 constrcutor 是上述两种情况 (a.__proto__ = null 时 a.constructor = undefined),则返回 ObjProto 。
var proto = _.isFunction(constructor) && constructor.prototype || ObjProto
_.isFunction(constructor) && constructor.prototype
constrcutor
var a = {}; a.__proto__ = null
a.__proto__ = null
a.constructor = undefined
ObjProto
后来又想了下,如果 constructor 是函数,那么它 的原型一定存在:
那么后面何必再判断 constructor.prototype 呢?有一点可以肯定的是如果 自己手动将 constructor.prototype = null 的时候这个判断是有效的,其他的确实想不到为什么要这个来判断,如果有谁懂,望告知
constructor.prototype
constructor.prototype = null
接着是 将 constructor 这个属性单独拿出来判断(但是为什么要这么做呢??不能也放入上述数组中??求告知) 其中 _.has() 使用 hasOwnProperty来判断,保证了不包含 原型上的 constructor
_.has()
hasOwnProperty
最后就是循环判断那6个不可枚举属性 其中 prop in obj很重要,那为啥要加这句呢?
prop in obj
var a = {}, keys = []; a.__proto__ = null collectNonEnumProps(a, keys); // 如果没有 `prop in obj`,那么返回的是 ` keys=['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']` // 如果有,keys = []
最后,大家尽量少改写原生对象的属性,避免不必要的错误
The text was updated successfully, but these errors were encountered:
No branches or pull requests
上面这段代码中,除了一般的使用 for...in 来取出属性名,后面还有一步判断是否有 可枚举的bug 情况,主要针对,ie<9下,for...in 的问题。不过我在 mdn 上查到
for...in
在 ie6 下都支持,所以可能之前编写这个库时 for...in 在ie<9下都不支持不过阅读这段代码还是能收获不少
首先
var hasEnumBug = !{ toString: null }.propertyIsEnumerable('toString')
在 ie<9 下,
{ toString: null }.propertyIsEnumerable('toString')
会返回false
,因此可以用此来判断是否是 ie<9 的浏览器注:现在ie 下的情况:
![image](https://user-images.githubusercontent.com/12515800/33524615-1d014cfa-d85b-11e7-9f6e-415cd60f2a74.png)
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
这是一些不可枚举的属性,除了
constructor
:var proto = _.isFunction(constructor) && constructor.prototype || ObjProto
这里上面代码里面注释了一些,不过还要说的一点是,
_.isFunction(constructor) && constructor.prototype
排除了 对象的constrcutor
是直接量的问题,并且排除了var a = {}; a.__proto__ = null
的情况,如果constrcutor
是上述两种情况 (a.__proto__ = null
时a.constructor = undefined
),则返回ObjProto
。后来又想了下,如果
![image](https://user-images.githubusercontent.com/12515800/33524676-3132cbe4-d85c-11e7-8af6-87fa962305a4.png)
constructor
是函数,那么它 的原型一定存在:那么后面何必再判断
constructor.prototype
呢?有一点可以肯定的是如果 自己手动将constructor.prototype = null
的时候这个判断是有效的,其他的确实想不到为什么要这个来判断,如果有谁懂,望告知接着是 将
constructor
这个属性单独拿出来判断(但是为什么要这么做呢??不能也放入上述数组中??求告知)其中
_.has()
使用hasOwnProperty
来判断,保证了不包含 原型上的constructor
最后就是循环判断那6个不可枚举属性
其中
prop in obj
很重要,那为啥要加这句呢?最后,大家尽量少改写原生对象的属性,避免不必要的错误
The text was updated successfully, but these errors were encountered: