understanding variable shadowing in javascript?

Viewed 216

i created a crypto object as follows:

var crypto = {
  encrypt: function(s) {

  }
};

crypto.encrypt("cat");

I would get the following error

Uncaught TypeError: crypto.encrypt is not a function

var crypt = {
  encrypt: function(s) {

  }
};

crypt.encrypt("cat");

this would work. I realized that there is already an inbuilt crypto object so the crypto object i defined was not being recognized.

My understanding is that the variables declared later will shadow variable declared previously.

For example when i create two objects like follows:

var test = {
  testing2: function() {
    return "there";
  }
}

var test = {
  testing: function() {
    return "hey";
  }
}

test.testing2()

and i call test.testing2() then the similar error is thrown because the second test variable has shadowed the first. So if variable shadowing works with self created variables then why is crypto not being shadowed? Is it the case that the predefined objects are always higher in priority so any self created objects will not shadow the window objects. I appreciate any insights into this. Thanks!

1 Answers

Usually, yes, variables declared later (with var) will simply overwrite vars declared earlier with the same name. The difference is that variables declared with var on the top level assign to window properties, and window.crypto is a property with a getter, but no setter:

console.log(
  Object.getOwnPropertyDescriptor(window, 'crypto')
);

So when you assign to window.crypto with var crypto, there's no setter, so nothing happens. Many other window properties behave the same way.

Consider using const or let instead:

const crypto = {

  encrypt: function(s) {

  }
};

crypto.encrypt("cat");

Or put it into an IIFE:

(() => {
  var crypto = {

    encrypt: function(s) {

    }
  };

  crypto.encrypt("cat");
})();

Or use a linter

You can also use use strict to make the error explicit:

'use strict';
var crypto = {

  encrypt: function(s) {

  }
};

console.log('successfully defined crypto');
crypto.encrypt("cat");

Related