// 例子如下
window.a = 1;
a in window; //返回false
'a' in window; //返回true
//這個貌似是正常的,和我們理解的一樣
var xx = 1;
console.log(xx in window); //false
console.log('xx' in window); //true
//但是這個就有點奇怪了,只聲明變量,結(jié)果兩種情況返回的的都是true,
var x;
console.log(x in window); //true
console.log('x' in window); //true
console.log(x); //undefined 我們打印下X 發(fā)現(xiàn)X其實就是undefined
// 所以其實 x in window 等價于 undefined in window 所以為true
首先要知道為什么,就必須先了解 in 操作符的用法。
如果指定的屬性在指定的對象或其原型鏈中,則in 運算符返回true
prop in object
1.prop
一個字符串類型或者 symbol 類型的屬性名或者數(shù)組索引(非symbol類型將會強(qiáng)制轉(zhuǎn)為字符串)。
2.objectName
檢查它(或其原型鏈)是否包含具有指定名稱的屬性的對象。
例如
// 數(shù)組
var trees = new Array("redwood", "bay", "cedar", "oak", "maple");
0 in trees // 返回true
3 in trees // 返回true
6 in trees // 返回false
"bay" in trees // 返回false (必須使用索引號,而不是數(shù)組元素的值)
"length" in trees // 返回true (length是一個數(shù)組屬性)
Symbol.iterator in trees // 返回true (數(shù)組可迭代,只在ES2015+上有效)
// 內(nèi)置對象
"PI" in Math // 返回true
// 自定義對象
var mycar = {make: "Honda", model: "Accord", year: 1998};
"make" in mycar // 返回true
"model" in mycar // 返回true
in右操作數(shù)必須是一個對象值。例如,你可以指定使用String構(gòu)造函數(shù)創(chuàng)建的字符串,但不能指定字符串文字。
var color1 = new String("green");
"length" in color1 // 返回true
var color2 = "coral";
"length" in color2 // 報錯(color2不是對象)
所以回到這個問題,
window.a = 1;
a in window; //返回false
'a' in window; //返回true
var xx = 1;
console.log(xx in window); //false
console.log('xx' in window); //true
var x;
console.log(x in window); //true
console.log('x' in window); //true
其實就是 a 是個變量,a in window 實際等于 1 in window,所以1 不在對象window或其原型鏈中,in 運算符返回false。
而'a' in window 我們window.a 定義過了,a已經(jīng)在window屬性中的,所以返回true
接著第二個例子 var xx = 1, 其實我們要知道這個js中 var 的全局變量的聲明是等價于 windw.xx = 1的, 明白了這個,所以 其實第二個例子和上面一樣。
第三個例子, var x; 其實可以等價于 window.x = undefined ; 所以在undefined in window的時候,我們可以看到window上 確實有undefined屬性,所以為true。 而'x' in window 與之前例子同理,window上已有x屬性所以為true。

打印window,我們確實看到xx, x, a 已經(jīng)是window的屬性,且x值為undefined。另外我們也在window上面找到了自帶的undefined屬性,可以證明我們的理論是正確的。

本文轉(zhuǎn)自https://blog.csdn.net/ddwddw4/article/details/88672440,侵刪