Keeping an eye on the count of globals...

R

Ry Nohryb

Keeping an eye on the count of global symbols might help you spot
unintentionally undeclared vars that turn into globals. Now with
Object.keys it seems to be as easy as:

Object.keys(window).length
--> 436

(function(){ k= 27; })();

Object.keys(window).length
--> 437
 
R

Ry Nohryb

Keeping an eye on the count of global symbols might help you spot
unintentionally undeclared vars that turn into globals. Now with
Object.keys it seems to be as easy as:

Object.keys(window).length
--> 436

(function(){ k= 27; })();

Object.keys(window).length
--> 437

Or is it better for any reason for the job at hand to use
Object.getOwnPropertyNames(window).length ?
 
R

Ry Nohryb

Or is it better for any reason for the job at hand to use
Object.getOwnPropertyNames(window).length ?

How about this one for monitoring globals during development ?

(function () {
var saved= Object.getOwnPropertyNames(window);
(function globalsMonitor (curr, names) {
curr= Object.getOwnPropertyNames(window);
if (curr.length !== saved.length) {
names= [];
curr.forEach(function (v,i,o) {
if (saved.indexOf(v) < 0) {
names.push( v+ " ["+ typeof window[v]+ "] : "+ window[v]+ "\r");
}
});
alert(names.length+ " new globals :\r"+ names);
saved= curr;
}
setTimeout(globalsMonitor, 1e3);
})();
})();

Whenever a new global is detected, an alert will pop up to tell us.
 
A

Asen Bozhilov

Ry said:
Keeping an eye on the count of global symbols might help you spot
unintentionally undeclared vars that turn into globals. Now with
Object.keys it seems to be as easy as:

Object.keys(window).length
--> 436

(function(){ k= 27; })();

Object.keys(window).length
--> 437

Don't you use debugger for this case? For example I use
`javascript.options.strict = true;` during development stage and if
there are undeclared assignments I get message in console.
 
R

Ry Nohryb

Don't you use debugger for this case? For example I use
`javascript.options.strict = true;` during development stage and if
there are undeclared assignments I get message in console.

My debuggars don't have that:
javascript
--> ReferenceError: Can't find variable: javascript
javascript.options
--> ReferenceError: Can't find variable: javascript

?

And, what if what you're debugging is neither strict code nor strict-
rules compliant ?
 
R

RobG

Keeping an eye on the count of global symbols might help you spot
unintentionally undeclared vars that turn into globals.


Where "now" means at some time in the future when implemented in your
browser of choice.

It may be useful to note that Object.kyes is an ES 5 feature and can
hardly be called ubiquitous at present.
Now with
Object.keys it seems to be as easy as:

Object.keys(window).length
--> 436

It may also be worth noting that the window object is not necessarily
the global object. Wouldn't it be better to use something like:

var globalObj = this;

function countGlobals() {
var keys;
if (globalObj && typeof Object.keys == 'function') {
keys = Object.keys(globalObj);
return keys && keys.length;
}
}
 
R

Ry Nohryb

Where "now" means at some time in the future when implemented in your
browser of choice.

It may be useful to note that Object.keys is an ES 5 feature and can
hardly be called ubiquitous at present.

You're right, currently (2010-08-10) it's only in Chrome and Safari,
it seems.
It may also be worth noting that the window object is not necessarily
the global object. Wouldn't it be better to use something like:

  var globalObj = this;

  function countGlobals() {
    var keys;
    if (globalObj && typeof Object.keys == 'function') {
      keys = Object.keys(globalObj);
      return keys && keys.length;
    }
  }

Yes, very good, thanks :)
 
R

Ry Nohryb

(...) is it better for any reason for the job at hand to use
Object.getOwnPropertyNames(window).length ?

Well, the difference between `Object.keys` and
`Object.getOwnPropertyNames` is that latter one returns names of all
(including non-enumerable) properties.

Considering that undeclared assignment (in non-strict mode) should
result in creation of (global) data property with [[Enumerable]]
attribute set to true (see 8.7.2 --> 8.12.5), I don't see a reason for
`Object.getOwnPropertyNames` here.

Yep. And it would be a slightly shorter loop:

[Object.keys(window).length,
Object.getOwnPropertyNames(window).length]
--> [730, 761]

But I'm thinking that OTOH, wouldn't it be a good thing to be able to
catch any fresh non-enumerable global symbols as well ?
 
R

Ry Nohryb

Well, to my knowledge, the only way to create non-enumerable property in
ES5 is to use `Object.defineProperty` (or any other method allowing to
set attributes — `Object.defineProperties`, `Object.create`, etc.)

And anyone using `defineProperty` (or similar methods) is likely
creating a property intentionally, contrary to unnoticed undeclared
assignment.

Or any third party script, GA for example ;-)
Using strict mode (once implemented; currently only in Besen, but
Mozilla is making a significant progress lately —
<http://kangax.github.com/es5-compat-table/strict-mode/>) might be a
better solution to undeclared assignments, where they result in
ReferenceError.
Probably.

You can also look into my "detect global" bookmarklet
(http://perfectionkills.com/detecting-global-variable-leaks/) or
Garrett's JScript RuntimeObject -based one
(http://dhtmlkitchen.com/?category=/Browsers/&date=2010/04/11/&entry=D...)

Well done, but I prefer mine :) haven't you tried it ? You should
load it as early as possible, and once installed it keeps monitoring
*fresh*new* globals creation in ~ real time. Really nice. BTW
Garrett's code is definitely too much IE-centric.

javascript:(function () {
var saved= Object.getOwnPropertyNames(window);
(function globalsMonitor (curr, names) {
curr= Object.getOwnPropertyNames(window);
if (curr.length !== saved.length) {
names= [];
curr.forEach(function (v,i,o) {
if (saved.indexOf(v) < 0) {
names.push( v+ " ["+ typeof window[v]+ "] : "+ window[v]+ "\r");
}
});
alert(names.length+ " new globals :\r"+ names);
saved= curr;
}
setTimeout(globalsMonitor, 1e3);
})();
})();

After "installing" it, just create a new global and an alert should
popup in no more than a second. Currently it only works in Chromes and
Safaris.
 
R

Ry Nohryb

Ry Nohryb said:
Garrett's code is definitely too much IE-centric.

[Jorge’s code]
Currently it only works in Chromes and Safaris.

Web Developers never fail to amaze me.

Hey, I'm using a *standard* (ES5) method ! The pity is that it's not
implemented yet (2010-08-22) in any browsers except Chrome and Safari.
But soon it will be...
 
D

David Mark

[Jorge’s code]
Currently it only works in Chromes and Safaris.
Web Developers never fail to amaze me.

Hey, I'm using a *standard* (ES5) method ! The pity is that it's not
implemented yet (2010-08-22) in any browsers except Chrome and Safari.
But soon it will be...

And every user out there will immediately upgrade. :) And even if
that were true, what does it buy you today?

Why don't you just use your buddy's lint tool? That's what I do. I
don't care for strict mode debugging as complaints about one-off
anonymous functions not returning values and access to undefined
properties seem silly to me (and obscure the real problems).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top