获取所有用户定义的窗口属性?

IT技术 javascript browser properties window-object
2021-02-09 13:57:55

有没有办法在javascript中找出所有用户定义的窗口属性和变量(全局变量)?

我试过了,console.log(window)但名单是无止境的。

5个回答

您还可以将窗口与窗口的干净版本进行比较,而不是尝试在运行时进行快照进行比较。我在控制台中运行了这个,但是你可以把它变成一个函数。

// 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);
}());
从 11 月开始,Chrome 的控制台无法results正确登录18,我必须让results全局然后记录它。虽然代码很棒!
2021-03-31 13:57:55

您需要自己完成这项工作。在第一时间阅读所有属性。从那时起,您可以将属性列表与静态列表进行比较。

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

所以现在,我们可以像

// on init
readGlobalProps();  // store current properties on global object

然后

window.foobar = 42;

findNewEntries(); // returns an array of new properties, in this case ['foobar']

当然,这里需要注意的是,您只能在脚本最早能够调用全局属性列表时“冻结”它。

但也许你应该提到它Object.getOwnPropertyNames是 ECMAScript 5 版的一部分。还过滤器和 Array.indexOf
2021-03-14 13:57:55
@NULL 好吧,过去几个月我习惯提到它,我觉得是时候继续前进了:)
2021-03-21 13:57:55
我认为这将是最接近完美的答案。
2021-03-26 13:57:55
@jAndy 可能会将readGlobalProps放入IIFE 中,这样它就会在您定义后立即调用?
2021-03-26 13:57:55
@jAndy 是时候继续前进了,我现在只支持 ie9 及更高版本,这是一个很好的答案,非常感谢。
2021-04-10 13:57:55

这与@jungy 的回答具有相同的精神,但我们可以用 3 行来完成:

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

首先我们添加一个隐藏的 iframe;然后我们针对 iframe 中的标准 JavaScript API 测试现有变量;然后我们删除 iframe。

为了更方便地工作,按字母顺序对结果进行排序可能很有用,并且仍然可以使用 3 行版本:

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

它可以打包成书签:

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';
“按时间顺序对结果进行排序可能很有用,并且在 3 行版本中仍然可能:......”你不是说按字母顺序吗?(按时间顺序意味着基于时间,而不是按字母/词汇排序)
2021-03-19 13:57:55
没错,固定。谢谢。
2021-04-02 13:57:55

我在 ChromeDev 工具的控制台中运行了它,它复制了所有用户定义的正确内容

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()));
如果您的页面有 iframe 并引发以下错误,请尝试使用以下--disable-web-security标志启动 chrome :“阻止了一个带有原点的框架”访问跨源框架。”
2021-03-14 13:57:55

也许这个?:

for (var property in window)
{
    if (window.hasOwnProperty(property))
        console.log(property)
}
它还将提供浏览器定义的属性
2021-04-08 13:57:55