Why this…
class Person
name: "initial name"
constructor: (@name) ->
class User extends Person
password: "initial password"
f = new User "Felds"
console.log f
console.log "my name is '#{f.name}' and my password is '#{f.password}'"
b = new User "Bob"
b.password = "bob's password"
console.log b
… when run through coffee -p test.coffee | node outputs this?
{ name: 'Felds' }
my name is 'Felds' and my password is 'initial password'
{ name: 'Bob', password: 'bob\'s password' }
Why doesn’t the password property show on console.log f ? Where is it stored and how is it retrieved?
The
'initial password'value is stored inPerson.prototype.password.Person.prototypeis an object with all the common attributes shared betweenPersoninstances. When you accessaPersonInstance.password, the password property is first looked up in theaPersonInstanceobject; if it’s not found there it will be looked up in its prototype, and then in its prototype’s prototype and so on.console.log fwill not showf‘s prototype properties, only the properties stored infthemselves (also known asf‘s own properties). When you assign Bob’s password withb.password = 'bob\'s password'you’re creating a newpasswordproperty inbitself, which will now be the value of accessingb.password, even thoughb‘s prototype still has the'initial password'value. I hope that made some sense =PBy storing
'initial password'in the prototype you’re sharing that value between all Person instances as a kind of default value. This is perfectly fine to do with strings or other primitive (immutable) types; but you have to take special care if you’re going to do it with arrays or other mutable objects, because the same object will be shared between all the class’ instances, and if one of them modifies it, e.g.@someArray.push 5, all the other ones are going to see it. In those cases, it’s usually preferable to initialize the attribute in the class constructor, like@someArray = [], to guarantee that each instance will have a different array/object attribute.