是否有办法找出所有用户定义的窗口属性和变量(全局变量)在javascript?
我试过console.log(window)
,但列表是无止境的。
您还可以将窗口与干净的窗口版本进行比较,而不是在运行时尝试快照进行比较。我是在控制台中运行的,但是你可以把它变成一个函数。
// 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);
}());
这和@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';
您需要自己完成这项工作。读取所有属性,在第一时间,你可以。从那时起,您可以将属性列表与静态列表进行比较。
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']
当然,这里需要注意的是,您只能在脚本能够最早调用它的时候"冻结"全局属性列表。
我在ChromeDev工具的控制台中运行了这个,它复制了所有用户定义的正确
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()));
窗口对象的属性按时间顺序排列。因此,在网页中包含的第一个脚本的开头创建一些具有唯一名称的变量并获取该属性的索引:
var abcdefghijklmnopqrstuvwxyz = true;
var firstOwnPropertyFound = Object.keys(window).indexOf('abcdefghijklmnopqrstuvwxyz');
然后在任何你想获得所有用户定义属性的数组使用:
let myProp = Object.keys(window).slice(firstOwnPropertyFound);
或者如果你想跳过前两个变量:
let myProp = Object.keys(window).slice(firstOwnPropertyFound + 2);
myProp变量数组包含您创建的所有属性名称。在我的测试网页中,例如:
Array(7) [
0: "abcdefghijklmnopqrstuvwxyz"
1: "firstOwnPropertyFound"
2: "st"
3: "clog"
4: "tstfnc"
5: "tstFNC1"
6: "obj"
length: 7
]
访问所有变量:
myProp.forEach(item => {
console.log(window[item]);
}
我使用这个,它工作。(抱歉我的英语不好)
我没有创建这个代码,这个答案是这个原始答案的改进版本。
改进如下:
- 封装在一个函数中,以便在需要时使用
- 显示属性的数据,而不仅仅是它的名称
(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);
})()
也许是这个?:
for (var property in window)
{
if (window.hasOwnProperty(property))
console.log(property)
}