所以,我正在编写一个函数,在调用函数时确定起始window
和新window
之间的差异。但是,没有记录任何内容:
var differences = (function() {
var original = {};
for (var i in window) {
if (window.hasOwnProperty(i)) {
original[i] = window[i];
}
}
// this is the area I refer to further down in my post
return function() {
// should find differences between original and new window
for (var i in window) {
if (!(original.hasOwnProperty(i)) && window.hasOwnProperty(i)) {
console.log(i + ": " + window[i]);
}
}
};
})();
var abc = 5;
differences(); // nothing is logged
所以,我决定检查原始副本中的abc
:
// after first for loop in foo differences function
console.log(original.hasOwnProperty("abc")); // true
console.log(original.abc);
// this logs that abc is defined as undefined
有人会认为,因为首先定义differences
,所以abc
对象中不应存在original
。但是,因为它确实存在于original
对象中,为什么它被定义为undefined
而不是5?
但是,让我更加困惑的是我写的hasOwnProperty
行
console.log(original.hasOwnProperty("abc"));
在JSFiddle中运行时会记录false
,但是如果我用JS创建一个空白的HTML文件,它会记录true
。
有人可以解释这些奇怪的事件吗?
答案 0 :(得分:1)
当您使用var
声明变量时,会在执行任何代码之前将其添加到最直接的execution context (这称为吊装顺便说一句,如果你想搜索主题)
想象一下以下
function foo() {
// note that the following doesn't throw an error
console.log(bar) // undefined
var bar = 5
console.log(bar) // 5
}
foo()
console.log(bar) // throw an error
调用该函数时,内部会发生以下步骤
如果变量是在函数外定义的,那么它最直接的执行上下文就是全局上下文,在Web浏览器中是window
对象
// note that the following doesn't throw an error
console.log(bar) // undefined
console.log(window.bar) // undefined
console.log(window.hasOwnProperty('bar')) // true
var bar = 5
console.log(bar) // 5
console.log(window.bar) // 5
但是,更令我困惑的是我写的hasOwnProperty行
console.log(original.hasOwnProperty("abc"));
在JSFiddle中运行时,它会记录为false,但如果我使用JS创建一个空白的HTML文件,则会记录为真。有人可以解释这些奇怪的事件吗?
JSFiddle的问题是不是代码是在iframe上运行,如果你检查由iffe创建的iframe,那么你编写的代码会被JSFiddle放入一个函数中JSFiddle你会看到以下
<html>
<head>
<script>
//<![CDATA[
window.onload=function(){
console.log(window.hasOwnProperty('bar')) // false
var bar = 5
}//]]>
</script>
</head>
<body>
</body>
</html>
&#13;
但是,如果您的代码位于script
标记内或外部脚本中,就像使用空白html一样,您将得到以下内容
console.log(window.hasOwnProperty('bar')) // true
var bar = 5
&#13;
答案 1 :(得分:0)
尝试创建一个IIFE,其中original
传递给包含要调用的函数的对象。请注意,!(original.hasOwnProperty(i))
将返回false
,console.log(i + ": " + window[i])
将不会在第二个for
循环中调用,因为window
的属性之前已设置为original
您可以在第!
个循环内的if
条件下移除for
运算符,在对象返回的调用函数可以查看console.log(i + ": " + window[i])
的结果;返回original
作为同一对象的属性值,以确定abc
和original
window
var differences = (function() {
var original = {};
for (var i in window) {
if (window.hasOwnProperty(i)) {
original[i] = window[i];
}
}
// this is the area I refer to further down in my post
return {
props: function() {
return (function(original) {
// should find differences between original and new window
for (var i in window) {
if ((original.hasOwnProperty(i)) && window.hasOwnProperty(i)) {
console.log(i + ": " + window[i]);
}
}
;
}(original))
},
o: original
};
})();
var abc = 5;
var diff = differences;
diff.props();
console.log(window["abc"], diff.o["abc"])