I'm learning JS. Kyle Simpson in his Book, YDKJS, writes that:
If a normal data accessor (see Chapter 3) property named foo is found anywhere higher on the [[Prototype]] chain, and it's not marked as read-only ( writable:true) then a new property called foo is added directly to myObject , resulting in a shadowed property.
function Foo(name) {
this.name = name;
}
Foo.prototype.myName = function() {
return this.name;
};
var a = new Foo( "a" );
var b = new Foo( "b" );
In the above snippet, it's strongly tempting to think that when a and b are created, the properties/functions on the Foo.prototype object are copied over to each of a and b objects. However, that's not what happens. When
myName
is not found on a or b , respectively, it's instead found (through delegation, see Chapter 6) on Foo.prototype . Reference Page 97
To test the same, I created a property val
on prototype object with value 1:
Foo.prototype.val = 1;
Since object a
is prototype linked, I incremented this property by 1:
a.val++;
But when I executed following two lines:
console.log(a.val);
console.log(Foo.prototype.val);
Result:
2
1
The result shows that a separate property val
is created on object a
with the incremented value 2, which seems contradicts (that its delegated) with his statement.
Where did I astray? Please guide
I think you may be confusing what happens with values on the prototype when assigning a value vs when creating an object using the constructor function.
For example, take the book's first example:
Foo.prototype.myName = function() {...};
var a = new Foo( "a" );
var b = new Foo( "b" );
As Kyle outlines in his book, when using the new
keyword to create objects a
and b
, the values from Foo.prototype
aren't created as properties directly on a
and b
(ie: own-properties), but instead, a
and b
's [[Prototype]]
s point to Foo.prototype
, which is where myName
is accessed.
In your example code, you're firstly creating a property called val
on the prototype:
Foo.prototype.val = 1;
and then incrementing val
. This increment is what then creates an own-property on a
. To show what's happening in more detail, the below is begin performed:
v--- creates an own-property directly on `a`
a.val = a.val + 1;
^--- accessing 1 from `Foo.prototype.val`
The a.val =
component of the above creates an own property called val
directly on the a
object, and the a.val + 1
is accessing the value you had previously set with Foo.prototype.val = 1;
via accessing a
via the [[Prototype]]
, and then adding 1
to it. As you're effectively doing an "assignment" here, you end up creating an own property on a
, which is a different operation from what the excerpt shown from Kyle's book is doing, where he is just creating a new object using the new
keyword.