0

So I have a question about this and just having normal variables in classes.

Normally we do something like this:

class Thingy {
  constructor(thing) {
    this.id = thing
  }
  printID() {
    console.log(this.id)
  }
}
let newthingy = new Thingy("ID1")
let newthingy2 = new Thingy("ID2")
newthingy.printID()
newthingy2.printID()

Which works just fine, however something like this will not:

class Thingy {
  constructor(thing) {
    let id = thing
  }
  printID() {
    console.log(id)
  }
}
let newthingy = new Thingy("ID1")
let newthingy2 = new Thingy("ID2")
newthingy.printID()
newthingy2.printID()

So I understand that newthingy will have no idea what id is, so won't it just look up the prototype chain back at the original class prototype? I realize it probably wouldn't get the right id but how come we get a id not defined error, should it attempt to look up the prototype chain first?

maazadeeb
  • 5,922
  • 2
  • 27
  • 40
msmith1114
  • 2,717
  • 3
  • 33
  • 84
  • Think of `let` kind of like `var`. When you have a function and define `var something = 'some string';` then `something` is not accessible from outside of that method. When you use `this` in the context of a class, it is accessible from anywhere in the class or anything that uses the class. – Joshua Terrill May 23 '17 at 03:39
  • It will be the same for var too in your second snippet. What are you trying to achieve by using let in your second snippet? – karthick May 23 '17 at 03:41
  • check out this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let – Howard Wang May 23 '17 at 03:54
  • Lets pretend it was var for instance then, it'd be the same right? – msmith1114 May 23 '17 at 05:04

3 Answers3

2

I believe it is all about scope. When you say...

let id = thing

... you are actually declaring a variable that is local to the constructor method. When you define ...

this.id = thing

... it is actually modifying a property value of the Thingy instance. And, when printID tries to access "id", it has no context to find "id" in.

pacifier21
  • 813
  • 1
  • 5
  • 13
  • Makes sense I guess, I keep forgetting im defining properties of X.object where X is `newthingy` for instance. I guess what confuses me is that I "expect" id to be defined, but im never actually making an object with a variable `id` technically am I? I mean the class definition is just a definition and itself isn't instantiated. – msmith1114 May 23 '17 at 05:06
  • 1
    @msmith1114: The confusion comes from the fact that people (admittedly they're mostly confused people) tend to mix two very different and incompatible concepts together: binding (how properties of objects are bound to an instance of an object) and scope (how compilers enforce variable access rules). Properties are technically not variables and variables are technically not properties (apart form the window object and global variables). If you look at the low level implementation most engines implement them as lookup chains but there are two types of chains: prototype chains and the scope chain – slebetman May 23 '17 at 05:38
1

This has absolutely nothing to do with the prototype. It's much simpler than you may make it out to be:

"Class methods" are merely functions which act on an object. The way they act on an object is through this. That is all. It's a normal function, which has implicit access to this, which is an object. Since in Javascript the value of this is decided at call time, this is an extremely malleable mechanism:

function foo() {
    console.log(this.bar);
}

foo.call({ bar: 'baz' });

let baz = { bar: 'baz' };
baz.foo = foo;
baz.foo();

As you see, you don't even need a class for this to work. A class merely formalises this into a certain pattern:

new Thingy creates a new object and calls the Thingy constructor on it, in the constructor you set this.id = thing, creating the id property on that new object. When you then call newthingy.printID(), you're calling the printID function setting its this context to the object created previously (newthingy), so this.id works.

The id value is transported from constructor to printID as a property on an object. If you just use id (instead of this.id), you're merely trying to access a local variable which doesn't exist.

deceze
  • 510,633
  • 85
  • 743
  • 889
1

'constructor' and 'printID' are both functions.Variables defined at them cannot be reached by others.

LinJI
  • 126
  • 5