Get all user defined window properties?
Solution 1
You would need to do the work for yourself. Read in all properties, on the first possible time you can. From that point on, you can compare the property list with your static one.
var globalProps = [ ];
function readGlobalProps() {
globalProps = Object.getOwnPropertyNames( window );
}
function findNewEntries() {
var currentPropList = Object.getOwnPropertyNames( window );
return currentPropList.filter( findDuplicate );
function findDuplicate( propName ) {
return globalProps.indexOf( propName ) === -1;
}
}
So now, we could go like
// on init
readGlobalProps(); // store current properties on global object
and later
window.foobar = 42;
findNewEntries(); // returns an array of new properties, in this case ['foobar']
Of course, the caveat here is, that you can only "freeze" the global property list at the time where your script is able to call it the earliest time.
Solution 2
You could also compare the window against a clean version of the window instead of trying to snapshot during runtime to compare against. I ran this in console but, you could turn it into a function.
// make sure it doesn't count my own properties
(function () {
var results, currentWindow,
// create an iframe and append to body to load a clean window object
iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe);
// get the current list of properties on window
currentWindow = Object.getOwnPropertyNames(window);
// filter the list against the properties that exist in the clean window
results = currentWindow.filter(function(prop) {
return !iframe.contentWindow.hasOwnProperty(prop);
});
// log an array of properties that are different
console.log(results);
document.body.removeChild(iframe);
}());
Solution 3
This is in the same spirit as @jungy 's answer but we can do it in 3 lines:
document.body.appendChild(document.createElement('div')).innerHTML='<iframe id="temoin" style="display:none"></iframe>';
for (a in window) if (!(a in window.frames[window.frames.length-1])) console.log(a, window[a])
document.body.removeChild($$('#temoin')[0].parentNode);
First we add a hidden iframe; then we test existing variables against the standard JavaScript API in the iframe; then we remove the iframe.
To work more conveniently, it could be useful to sort the results in alphabetical order, and it's still possible in a 3 lines version:
document.body.appendChild(document.createElement('div')).innerHTML='<iframe id="temoin" style="display:none"></iframe>';
Object.keys(window).filter(a => !(a in window.frames[window.frames.length-1])).sort().forEach((a,i) => console.log(i, a, window[a]));
document.body.removeChild($$('#temoin')[0].parentNode);
And it can be packed into a bookmark:
javascript:document.body.appendChild(document.createElement('div')).innerHTML='<iframe%20id="temoin"%20style="display:none"></iframe>';Object.keys(window).filter(a=>!(a%20in%20window.frames[window.frames.length-1])).sort().forEach((a,i)=>console.log(i,a,window[a]));document.body.removeChild(document.querySelectorAll('#temoin')[0].parentNode);throw 'done';
Solution 4
I ran this in the console in ChromeDev tool and it copied all of the user defined proper
function getUserDefinedKeys() {
const globalKeys = ["postMessage","blur","focus","close","parent","opener","top","length","frames","closed","location","self","window","document","name","customElements","history","locationbar","menubar","personalbar","scrollbars","statusbar","toolbar","status","frameElement","navigator","origin","external","screen","innerWidth","innerHeight","scrollX","pageXOffset","scrollY","pageYOffset","visualViewport","screenX","screenY","outerWidth","outerHeight","devicePixelRatio","clientInformation","screenLeft","screenTop","defaultStatus","defaultstatus","styleMedia","onanimationend","onanimationiteration","onanimationstart","onsearch","ontransitionend","onwebkitanimationend","onwebkitanimationiteration","onwebkitanimationstart","onwebkittransitionend","isSecureContext","onabort","onblur","oncancel","oncanplay","oncanplaythrough","onchange","onclick","onclose","oncontextmenu","oncuechange","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onfocus","oninput","oninvalid","onkeydown","onkeypress","onkeyup","onload","onloadeddata","onloadedmetadata","onloadstart","onmousedown","onmouseenter","onmouseleave","onmousemove","onmouseout","onmouseover","onmouseup","onmousewheel","onpause","onplay","onplaying","onprogress","onratechange","onreset","onresize","onscroll","onseeked","onseeking","onselect","onstalled","onsubmit","onsuspend","ontimeupdate","ontoggle","onvolumechange","onwaiting","onwheel","onauxclick","ongotpointercapture","onlostpointercapture","onpointerdown","onpointermove","onpointerup","onpointercancel","onpointerover","onpointerout","onpointerenter","onpointerleave","onselectstart","onselectionchange","onafterprint","onbeforeprint","onbeforeunload","onhashchange","onlanguagechange","onmessage","onmessageerror","onoffline","ononline","onpagehide","onpageshow","onpopstate","onrejectionhandled","onstorage","onunhandledrejection","onunload","performance","stop","open","alert","confirm","prompt","print","queueMicrotask","requestAnimationFrame","cancelAnimationFrame","captureEvents","releaseEvents","requestIdleCallback","cancelIdleCallback","getComputedStyle","matchMedia","moveTo","moveBy","resizeTo","resizeBy","scroll","scrollTo","scrollBy","getSelection","find","webkitRequestAnimationFrame","webkitCancelAnimationFrame","fetch","btoa","atob","setTimeout","clearTimeout","setInterval","clearInterval","createImageBitmap","onappinstalled","onbeforeinstallprompt","crypto","indexedDB","webkitStorageInfo","sessionStorage","localStorage","chrome","onformdata","onpointerrawupdate","speechSynthesis","webkitRequestFileSystem","webkitResolveLocalFileSystemURL","openDatabase","applicationCache","caches","ondevicemotion","ondeviceorientation","ondeviceorientationabsolute","WebUIListener","cr","assert","assertNotReached","assertInstanceof","$","getSVGElement","getDeepActiveElement","findAncestorByClass","findAncestor","disableTextSelectAndDrag","isRTL","getRequiredElement","queryRequiredElement","appendParam","createElementWithClassName","ensureTransitionEndEvent","scrollTopForDocument","setScrollTopForDocument","scrollLeftForDocument","setScrollLeftForDocument","HTMLEscape","elide","quoteString","listenOnce","hasKeyModifiers","isTextInputElement"];
return Object.fromEntries(Object.entries(window).filter(([key]) => !globalKeys.includes(key)));
}
const getCircularReplacer = () => {
const seen = new WeakSet();
return (key, value) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) {
return;
}
seen.add(value);
}
return value;
};
};
copy(JSON.stringify(getUserDefinedKeys(), getCircularReplacer()));
Related videos on Youtube
GriffLab
Updated on June 07, 2022Comments
-
GriffLab about 2 years
Is there a way to find out all user defined window properties and variables (global variables) in javascript?
I tried
console.log(window)
but the list is endless.-
Bergi almost 10 yearsRelated (if not duplicate): Fetching all (javascript) global variables in a page, Javascript - dumping all global variables
-
hippietrail about 9 years@Bergi: Which answer here covers my question that was just marked as a dupe of this? Are you saying the question is a dupe even though the answers are not. Should the answer about
keys()
be moved from my question or are you saying that one's wrong and even though the answers here look outdated one of these is the right answer?? -
Bergi about 9 years@hippietrail: I don't see why the answers here would be outdated. (How) don't they work for you? It seems to be just what you want, if I didn't misunderstood your question.
-
-
bugwheels94 about 11 yearsit will also give browser defined property
-
Andreas Louv about 11 yearsI think this would be the closest to a perfect answer .
-
Andreas Louv about 11 yearsBut maybe you should mention that
Object.getOwnPropertyNames
is part of the ECMAScript 5 Edition. Also filter and Array.indexOf -
jAndy about 11 years@NULL well, I was used to mention it for the last couple of month, I feel its time to move on :)
-
GriffLab about 11 years@jAndy definetely time to move on, I only support ie9 and above now, this is a brilliant answer thanks alot.
-
GriffLab about 11 years@jAndy maybe put the
readGlobalProps
in an IIFE that way it would be called as soon as you define it? -
jAndy about 11 years@GriffLab Yes. I guess the same way assuming that people don't worry about legacy browsers, I'm assuming they put their application logic in closured, private scopes :-)
-
hippietrail about 9 yearsDoes
keys(window)
not take care of most of the filtering? -
hippietrail about 9 yearsThis won't be any use from a userscript (Greasemonkey, Tapermonkey) since I don't believe userscript are guaranteed to run before the js in the page. What would the second best method be for that case?
-
yckart about 7 years@hippietrail Since you don't believe, nothing will ever be...? Believe me there's more out there, the Greasemonkey
@run-at
for example. -
Bigood over 5 yearsChrome's console doesn't log
results
properly as of nov. 18, I had to makeresults
global then log it. Awesome code though! -
Venryx about 5 years"it could be useful to sort the results in chronological order, and it's still possible in a 3 lines version: ..." Don't you mean alphabetical order? (chronological would mean based on time, not alphabetical/lexical sort)
-
Siltaar about 5 yearsTrue, fixed. Thanks.
-
Trent almost 4 yearsIf your page has iframes and throws the following error, try launching chrome with the
--disable-web-security
flag: "Blocked a frame with origin "" from accessing a cross-origin frame."