GriffLab
GriffLab

Reputation: 2166

Get all user defined window properties?

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.

Upvotes: 52

Views: 20975

Answers (7)

Diego Fortes
Diego Fortes

Reputation: 9800

I didn't create this code, this answer is an improved version of this original answer.

The improvements are:

  1. Wrapped around a function to use whenever needed
  2. Show the property's data, not only its name

(function showAllNonNativeWindowProperties(){

     var results, currentWindow,
  
    iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    document.body.appendChild(iframe);
  
    currentWindow = Object.getOwnPropertyNames(window);
 
    results = currentWindow.filter(function(prop) {
        return !iframe.contentWindow.hasOwnProperty(prop);
    });

    for (var each of results.sort()){
        console.log(`${each}: `, window[`${each}`]);
    }
    
    document.body.removeChild(iframe);
})()

Upvotes: 0

Raza
Raza

Reputation: 3383

I ran this in the console in ChromeDev tool and it copied all of the user defined proper

const 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()));

Upvotes: 3

Marek Štafl
Marek Štafl

Reputation: 11

The properties of window object are in chronological order. So, create some variable with unique name at the beginning of your first script included in your webpage and get the index of this property:

var abcdefghijklmnopqrstuvwxyz = true;
var firstOwnPropertyFound = Object.keys(window).indexOf('abcdefghijklmnopqrstuvwxyz');

Then anywhere you want to get array of all user defined properties use:

let myProp = Object.keys(window).slice(firstOwnPropertyFound);

or if you want to skip the first two variables:

let myProp = Object.keys(window).slice(firstOwnPropertyFound + 2);

The myProp variable is array contains all property names you created. In my test webpage for example:

Array(7) [
  0: "abcdefghijklmnopqrstuvwxyz"
  1: "firstOwnPropertyFound"
  2: "st"
  3: "clog"
  4: "tstfnc"
  5: "tstFNC1"
  6: "obj"
  length: 7
]

Then access all variables:

myProp.forEach(item => {
  console.log(window[item]);
}

I use this and it works. (Sorry for my bad English)

Upvotes: 1

Siltaar
Siltaar

Reputation: 173

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';

Upvotes: 12

jungy
jungy

Reputation: 3087

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);
}());

Upvotes: 119

jAndy
jAndy

Reputation: 236122

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.

Upvotes: 12

LonelyWebCrawler
LonelyWebCrawler

Reputation: 2916

Maybe this?:

for (var property in window)
{
    if (window.hasOwnProperty(property))
        console.log(property)
}

Upvotes: -6

Related Questions