3

I'm kind of new to JS, while reading the document from mozilla.org, I read that when declaring a const in global, it doesn't become a property of the global object. My question is, if so, where is the property stored?

For example:

const a = 'HI!';

function hello() {
  console.log(this.a); // undefined
}

hello();

This logs out undefined.

Instead of assigning it with

global.a = 'HI!'

Are there other ways I can access a with this?

DilbertFan
  • 111
  • 1
  • 1
  • 9
hkisthebest
  • 67
  • 1
  • 6
  • 1
    `const` doesn't create a property to the global object like `var` does. Refer the variables using their name. Notice, that in strict mode, `this` in `hello` would be `undefined`, and your code would throw an error. – Teemu Mar 09 '19 at 10:02
  • Why do you want to access `a` via `this` in particular? – VLAZ Mar 09 '19 at 10:07
  • [Related](https://stackoverflow.com/questions/28776079/do-let-statements-create-properties-on-the-global-object), but maybe not a dup, since the subject is `let`. – Teemu Mar 09 '19 at 10:10

3 Answers3

3

If you want to access a const or let variable (they behave identically in terms of access) that is in an outer scope, then you can do it by name

const outerVariable = 'HI!';

function hello() {
  console.log("access from inner scope", outerVariable); 
}

hello();

That works unless the variable is shadowed - a new variable with the same name is created in an inner scope

const outerVariable = 'HI!';

function hello() {
  const outerVariable = "impossible to access the outer declaration";
  console.log("access from inner scope", outerVariable); 
}

hello();

If you want to access it using the this context, then you can set the context of the function using Function#call(), Function#apply(), or Function#bind().

const a = 'HI!';

function hello() {
  console.log("access from context", this.a); 
}

hello(); //undefined - it's not in the context

const newContext = {a : a}; //the new value of "this"
hello.call(newContext); //HI!
hello.apply(newContext); //HI!

const boundFunction = hello.bind(newContext); //"this" will always be newContext for boundFunction
boundFunction(); //HI!

In this case .call() and .apply() are equivalent but in general they are subtly different when more parameters are passed

VLAZ
  • 18,437
  • 8
  • 35
  • 54
  • I'm a little confused here, so what you mean is that if I declare a variable _a_ with `const` at global scope, I still can't access it using `global.a`? – hkisthebest Mar 09 '19 at 13:52
  • @user8480342 `let` and `const` variables do not add a property to the global object when declared in the global scope. It's how their spec was written, so the behaviour is consistent with that. It is *different* to `var` declarations that explicitly do add a property to the global object when declared in the global scope. – VLAZ Mar 09 '19 at 13:55
  • Got it. Thanks for your reply! – hkisthebest Mar 09 '19 at 14:29
2

Information about const :

With const you can define immutable variables (constants).

const PI = 3.1415;
PI = 5; // "TypeError: Assignment to constant variable.

However, new items can still be pushed into an array constant or added to an object.

const someArr = [3, 4, 5];
someArr.push(6);

Now, accessing value inside function using this keyword , will give value only for functions block scope .

So, to access const a inside function you can use :

const a = 'HI!';

function hello() {
  console.log(this.a); // undefined <- this refer to function hello's scope
  console.log(a);   // HI!
}
Saurabh Mistry
  • 8,903
  • 4
  • 33
  • 51
  • Hi! Thanks for your response, in your last code, I added `var a = 'Hello~'` in the `hello` function, but it still logs out `undefined`. If _this_ is referring function hello's scope, why can't I still access it. I thought when you declare a function outside of an object, `this` simply means the global object, since console loging _this_ in the global scope gives you _window_ object or _global_ object. – hkisthebest Mar 09 '19 at 14:11
  • you can direct access var a inside console log in hello function , no ned to use this.a – Saurabh Mistry Mar 09 '19 at 14:23
1

It is declared in the block you are in. You can still access it from the same block scope (and the scopes that are declared in it), but not with window.a or global.a from any scope.

So - this would work:

const a = 1;

function b() {console.log(a);}

These however, would not:

window.a;
global.a;
Pärt Johanson
  • 1,312
  • 9
  • 13
  • The arrow functions aren't explicitly needed here, the function would become a [closure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) – James Mar 09 '19 at 10:22
  • True - I edited the post to make it less confusing. @James – Pärt Johanson Mar 09 '19 at 10:23