2

So, I was writing a function that determined the differences between the starting window, and the new window whenever the function is called. However, nothing was logged:

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

So, I decided to check what abc was in the original copy:

// 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

One would think that because differences is defined first, that abc shouldn't exist in the original Object. But, since it does exist in the original Object, why is it defined as undefined and not 5?

But, what confuses me even more is the hasOwnProperty line I wrote

console.log(original.hasOwnProperty("abc"));

when ran in JSFiddle it logs false, but if I make a blank HTML file with JS, it logs true.

Can someone explain these odd occurrences?

anonymous
  • 23
  • 8

2 Answers2

0

Try creating an IIFE where original is passed to an object which includes function to be called. Note, !(original.hasOwnProperty(i)) would return false, console.log(i + ": " + window[i]) would not be called in second for loop, as properties of window were previous set at original.

You can remove ! operator at if condition within second for loop, call function returned at object to view results of console.log(i + ": " + window[i]); return original as value of property at same object to determine if abc is defined at both original and 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"])
guest271314
  • 1
  • 15
  • 104
  • 177
  • I'm confused, why would I not want `!(original.hasOwnProperty(i))`? To detect differences between two objects, you check to see if one object has a property and the other one doesn't. – anonymous May 22 '16 at 02:02
  • @anonymous _"why would I not want `!(original.hasOwnProperty(i))`? To detect differences between two objects, you check to see if one object has a property and the other one doesn't."_ You can include `!` operator before `(original.hasOwnProperty(i))`. No properties should be logged at `console.log(i + ": " + window[i]);` at second `for` loop, as `if` condition should return `false` – guest271314 May 22 '16 at 02:09
0

When you declare a variable using var it gets added to the most immediate execution context before any code is executed (this is known as hoisting by the way if you want to search on the topic)

Imagine the following

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

When the function is called the following steps occur internally

  • An execution context is created
  • All the functions/variable declarations get defined on the execution context
  • The code is executed

If the variable is defined outside a function then its most immediate execution context is the global context which in web browsers is the window object

  // 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

But, what confuses me even more is the hasOwnProperty line I wrote console.log(original.hasOwnProperty("abc")); when ran in JSFiddle it logs false, but if I make a blank HTML file with JS, it logs true.

Can someone explain these odd occurrences?

The problem with JSFiddle is not that the code is run on an iframe, it's that the code you write is put inside a function by JSFiddle, if you inspect the iframe created by JSFiddle you will see the following

<html>
  <head>
  <script>
//<![CDATA[
window.onload=function(){
console.log(window.hasOwnProperty('bar'))  // false
var bar = 5
}//]]> 
  </script>
  </head>
  <body>
  </body>
</html>

However if your code is inside a script tag or in an external script just like you did with a blank html you get the following

console.log(window.hasOwnProperty('bar'))  // true
var bar = 5
Community
  • 1
  • 1
Mauricio Poppe
  • 4,817
  • 1
  • 22
  • 30