preciseTime()
In this era loads of+new Date
, JSC offers since quite a while a handy global function called preciseTime().Since this function offers more accuracy than milliseconds, and I am talking about microseconds, which is 1/1000 of a millisecond, it's the best option we have to measure benchmarks or be sure that some time elapsed between two statements in a synchronous code flow.
You might don't know that a loop between
new Date
and another new Date
could produce completely unexpected results such a negative integer which is kinda unexpected since zero is the best case we would consider.This behavior is behind ticks and clocks, more or less same reason
setTimeout
or setInterval
have never been accurate in therms of delay.preciseTime, this is the obvious name of my latest git repository, could be shimmed or polyfilled quite easily via a node module I can't npm install for some reason, or through
java.lang.System.nanoTime
for Rhino.enjoy!
Object.getPropertyNames()
In MDN Proxy Fundamental Traps chapter there are two functions I was kinda waiting for, and one of these isObject.getPropertyNames()
.As you might know,
Object.keys(object)
returns an array of enumerable object properties.A similar behavior could be obtained via this shim:
// warning: this is not fully ES5 standard
"keys" in Object || !function(hasOwnProperty){
Object.keys = function keys(object) {
var keys = [], key;
for (key in object)
// not considering IE < 9 quirks
hasOwnProperty.call(object, key) && keys.push(key);
;
return keys;
};
}({}.hasOwnProperty);
On the other hand, Object.getOwnPropertyNames returns an Array of all properties defined in the object, even those not enumerable or as getters/setters, but without considering inherited properties.
For all ES3 browsers is basically the same of above
Object.keys()
shim since it's not possible to define not enumerable properties in a meaningful way.To be really honest, probably all IE < 9 browsers should use the check over
isPropertyEnumerable()
check via Object.keys
, and leave the provided shim as it is since actually, those not enumerable properties are those that this function could return in a meaningful way, and talking about shims ... never mind ...In ES5 world there's no other way to retrieve all properties names defined in an object so this methods is pure awesomeness!
Right ... What About Object.getPropertyNames()
What is not possible right now, and in a world where inheritance is all over the place as JS world is, is the ability to retrieve not only own properties, but inherited properties too.In a duck typed system we need to know all characteristics of an object to be sure "it's a duck". Right now there's no standard way to obtain all properties an object could use, and this is where
Object.getPropertyNames()
becomes handy: you receive all inherited properties of an object too, together, of course, with own properties.In my shim, this is obtained through the
__proto__
de facto standard property.At this point we can recognize a duck properly, the only method eventually missing is the one able to give us a list of not enumerable properties per each object ... but with these tools, we can create one, if truly necessary.
Object.getPropertyDescriptor()
Oh well, this is about another annoying thing ... the fact we know thatobj instanceof Class
but we have to be upside-down to know if a property, defined as default in the Class.prototype
has been redefined or it's simply that bloody default.This is about this method, shimmed in the previous gist as well, and able to retrieve the descriptor of a property that might, or might not, be inherited. How cool is that?
The only thing I am not sure about, is if the method should consider up to
prototype === null
, including Object.prototype
or not ... right now is not, since I believe nobody would ever check for hasownProperty
descriptor, as example, with a generic object.global methods, classes, and shit
This is more a hint, whenever you are curious about what's exposed through your global object, you can simply perform this check, and inside an about:blank page:
console.log(
Object.getOwnPropertyNames(this).sort().join("\n")
);
Where if you want alphabetic order, you might consider this elaborated version if previous one did not work as expected.
Run it once in your browser, environment, console:
!function(global){
function alphabetically(a, b){
var
alen = a.length,
blen = b.length,
len = Math.min(alen, blen),
i = 0,
ac, bc, c
;
while (i < len) {
ac = a.charCodeAt(i);
bc = b.charCodeAt(i);
c = ac - bc;
if (c) return c;
++i;
}
return alen - blen;
}
var getOwnPropertyNames = Object.getOwnPropertyNames;
if (!getOwnPropertyNames) {
getOwnPropertyNames = function getOwnPropertyNames(object) {
var hasOwnProperty = {}.hasOwnproperty, keys = [], key;
for (key in object)
hasOwnProperty.call(object, key) && keys.push(key)
;
return keys;
};
}
function getAllKeys(object, ordered) {
var keys = getOwnPropertyNames(object);
ordered && keys.sort(alphabetically);
return keys;
}
console.log(getAllKeys(global,1).join("\n"));
}(this);
8 comments:
Your `Object.keys` implementation doesn't follow spec. It should throw a TypeError when passed a non-Object type. See http://es5.github.com/#x15.2.3.14. I don't see much use of shimming `Object.keys` when other ES5 methods are required and the `keys` shim isn't spec compliant or covering common iteration issues. Instead why not make a private utility function and use that or native `Object.keys` if it exists.
Instead of using a compare function with `Array#sort` why not just use `sort` without a compare function? I compared results of things like `["zz", "AA", "ZZ", "aa", "01"]` with and without your compare function and they both returned the same order of `["01", "AA", "ZZ", "aa", "zz"]`.
I was testing with real global data and could not remember why I had to use that function to grant same results cross platform ...
Object.keys was an example, lo-dash orunderscore are surely better utilities than that 1 minute shim ;-)
actually just sort() looks fine ... oh well, I have too many nighties installed :D
About preciseTime, I think it would be good if I took my old http://iejst.codeplex.com/ project and reflect that api name, so you could cross test on IE too :P
but would anyone use it if I update it?
here the answer ... about using that ... why are you interested in older IE tests ... you already know these performs crap :D
Why you ask?
1) Because I can
2) Because I have already done it :P
3) Because if performance are crap that not means you shouldn't look for it, sometimes if it performs poor in IE is a "smell" that something is wrong with you code, and you know, some people are still forced to use IE nowadays, so I though it would be useful to give these poor guys a way to profile their code.
Anyway I don't mind, I though it would be good to support ie6+, but seems like you're not interested, I mean, I can understand this, I'm not interested in ie<8 anymore.
Oh, totally unrelated but probably it would be a good idea to support msNow, oNow and mozNow too, if ever they will implement it, you will already work.
Post a Comment