JavaScript中的全局对象

3
如果我在Chrome中运行这段代码:
for(var i in window){console.log(i)}

我看到了很多以下的属性。

但是如果我运行这段代码:

console.log(window.hasOwnProperty("parseInt"))
console.log(window.hasOwnProperty("undefined"))

我同时得到了true

为什么.hasOwnProperty()返回true,但它在for-in循环产生的属性列表中没有显示出来?

循环结果:

top VM1531:2
window VM1531:2
location VM1531:2
external VM1531:2
chrome VM1531:2
document VM1531:2
getInnerFunction VM1531:2
theInnerFunction VM1531:2
__commandLineAPI VM1531:2
i VM1531:2
speechSynthesis VM1531:2
localStorage VM1531:2
sessionStorage VM1531:2
applicationCache VM1531:2
webkitStorageInfo VM1531:2
indexedDB VM1531:2
webkitIndexedDB VM1531:2
crypto VM1531:2
CSS VM1531:2
performance VM1531:2
console VM1531:2
devicePixelRatio VM1531:2
styleMedia VM1531:2
parent VM1531:2
opener VM1531:2
frames VM1531:2
self VM1531:2
defaultstatus VM1531:2
defaultStatus VM1531:2
status VM1531:2
name VM1531:2
length VM1531:2
closed VM1531:2
pageYOffset VM1531:2
pageXOffset VM1531:2
scrollY VM1531:2
scrollX VM1531:2
screenTop VM1531:2
screenLeft VM1531:2
screenY VM1531:2
screenX VM1531:2
innerWidth VM1531:2
innerHeight VM1531:2
outerWidth VM1531:2
outerHeight VM1531:2
offscreenBuffering VM1531:2
frameElement VM1531:2
clientInformation VM1531:2
navigator VM1531:2
toolbar VM1531:2
statusbar VM1531:2
scrollbars VM1531:2
personalbar VM1531:2
menubar VM1531:2
locationbar VM1531:2
history VM1531:2
screen VM1531:2
postMessage VM1531:2
close VM1531:2
blur VM1531:2
focus VM1531:2
ondeviceorientation VM1531:2
ondevicemotion VM1531:2
onautocompleteerror VM1531:2
onautocomplete VM1531:2
onunload VM1531:2
onstorage VM1531:2
onpopstate VM1531:2
onpageshow VM1531:2
onpagehide VM1531:2
ononline VM1531:2
onoffline VM1531:2
onmessage VM1531:2
onhashchange VM1531:2
onbeforeunload VM1531:2
onwaiting VM1531:2
onvolumechange VM1531:2
ontoggle VM1531:2
ontimeupdate VM1531:2
onsuspend VM1531:2
onsubmit VM1531:2
onstalled VM1531:2
onshow VM1531:2
onselect VM1531:2
onseeking VM1531:2
onseeked VM1531:2
onscroll VM1531:2
onresize VM1531:2
onreset VM1531:2
onratechange VM1531:2
onprogress VM1531:2
onplaying VM1531:2
onplay VM1531:2
onpause VM1531:2
onmousewheel VM1531:2
onmouseup VM1531:2
onmouseover VM1531:2
onmouseout VM1531:2
onmousemove VM1531:2
onmouseleave VM1531:2
onmouseenter VM1531:2
onmousedown VM1531:2
onloadstart VM1531:2
onloadedmetadata VM1531:2
onloadeddata VM1531:2
onload VM1531:2
onkeyup VM1531:2
onkeypress VM1531:2
onkeydown VM1531:2
oninvalid VM1531:2
oninput VM1531:2
onfocus VM1531:2
onerror VM1531:2
onended VM1531:2
onemptied VM1531:2
ondurationchange VM1531:2
ondrop VM1531:2
ondragstart VM1531:2
ondragover VM1531:2
ondragleave VM1531:2
ondragenter VM1531:2
ondragend VM1531:2
ondrag VM1531:2
ondblclick VM1531:2
oncuechange VM1531:2
oncontextmenu VM1531:2
onclose VM1531:2
onclick VM1531:2
onchange VM1531:2
oncanplaythrough VM1531:2
oncanplay VM1531:2
oncancel VM1531:2
onblur VM1531:2
onabort VM1531:2
onwheel VM1531:2
onwebkittransitionend VM1531:2
onwebkitanimationstart VM1531:2
onwebkitanimationiteration VM1531:2
onwebkitanimationend VM1531:2
ontransitionend VM1531:2
onsearch VM1531:2
getSelection VM1531:2
print VM1531:2
stop VM1531:2
open VM1531:2
alert VM1531:2
confirm VM1531:2
prompt VM1531:2
find VM1531:2
scrollBy VM1531:2
scrollTo VM1531:2
scroll VM1531:2
moveBy VM1531:2
moveTo VM1531:2
resizeBy VM1531:2
resizeTo VM1531:2
matchMedia VM1531:2
getComputedStyle VM1531:2
getMatchedCSSRules VM1531:2
webkitConvertPointFromPageToNode VM1531:2
webkitConvertPointFromNodeToPage VM1531:2
requestAnimationFrame VM1531:2
cancelAnimationFrame VM1531:2
webkitRequestAnimationFrame VM1531:2
webkitCancelAnimationFrame VM1531:2
webkitCancelRequestAnimationFrame VM1531:2
captureEvents VM1531:2
releaseEvents VM1531:2
btoa VM1531:2
atob VM1531:2
setTimeout VM1531:2
clearTimeout VM1531:2
setInterval VM1531:2
clearInterval VM1531:2
TEMPORARY VM1531:2
PERSISTENT VM1531:2
showModalDialog VM1531:2
webkitRequestFileSystem VM1531:2
webkitResolveLocalFileSystemURL VM1531:2
openDatabase VM1531:2
addEventListener VM1531:2
removeEventListener VM1531:2
dispatchEvent

1
为什么不可能呢?它们都是全局符号,否则它们会在哪里呢? - Pointy
8
for...in循环并不会遍历所有的属性,只会遍历那些被标记为可迭代的属性。 - Pointy
@Pointy。如果您是正确的,我想是的。我以为这都是属性。写下你的答案。 - pethel
1个回答

7

通过将对象属性标记为不可“枚举”,可以将其从迭代机制中隐藏:

var foo = { a: "Hello", b: "World" };
Object.defineProperty(foo, "c", { value: "where am I?" });

默认情况下,使用defineProperty()定义的属性不会被枚举,因此如果您在对象"foo"上运行for ... in循环,您将看不到"c"。

当然,全局对象具有各种神奇属性,但基本的“可枚举”标志仍然适用。至于为什么“parseInt”和“undefined”不可枚举,我无从得知。

编辑 - cookie monster在评论中指出,Object.getOwnPropertyNames()函数返回非枚举属性的名称。但是Object.keys()则不会。因此,您可以利用这种差异来查看一个对象是否具有非枚举属性:

 function hasSneakyProperties(o) {
     return Object.getOwnPropertyNames(o).length !== Object.keys(o).length;
 }

我不知道为什么有人会这样做,但是就是这样。


2
当然,它们不可枚举因为规范是这样规定的。 :P(“*除非另有规定,全局对象的标准内置属性具有属性{[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}*”) - apsillers
@apsillers 哈哈,是的,我想到了它在规范中(尽管我没有检查);我的意思是关于为什么它们不可枚举的原理。 - Pointy
2
值得注意的是,他可以使用 Object.getOwnPropertyNames(window) 来获取所有自有属性的完整列表,并使用 Object.getOwnPropertyDescriptor(window, "undefined") 来检查其设置。 - cookie monster
这篇文章值得一读:https://dev59.com/22Mm5IYBdhLWcg3wFLw4 - Nico

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接