Closed rookieLink closed 4 years ago
_.keys = function(obj) {
if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj);
var keys = [];
for (var key in obj) if (has(obj, key)) keys.push(key);
// Ahem, IE < 9.
if (hasEnumBug) collectNonEnumProps(obj, keys);
return keys;
};
_.isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
Here you can verify the function
@rookieLink If you do just this,
function A (){}
A.prototype.toString = 'original value';
var a = new A();
Then a.toString
is only an inherited property of a
and _.keys(a)
will be []
. The internal structure of a
looks like this ([[Prototype]]
is an abstract property of each object that you cannot access directly):
{
[[Prototype]]: {
constructor: A,
toString: 'original value'
}
}
If you now also do this:
a.toString = 'new value';
Then you create an extra own property on a
that shadows the toString
property of the prototype:
{
toString: 'new value',
[[Prototype]]: {
constructor: A,
toString: 'original value'
}
}
So it is important to understand that when you do
A.prototype.toString = 'original value';
this just sets a “default value” for the toString
property of instances of A
in case they don’t have an own property with that name.
Hope this answers your question. I will close this issue now, but feel free to comment again.
I read underscore's code about _.keys() if I want to invoke the code in IE7, there will be: ` function A (){} A.prototype.toString = 'test';
var a = new A(); a.toString = 'test'; _.keys(a); //there should be [] rather than ['toString']? ` right? I need some help