Home > Net >  Property Shadowing Issue
Property Shadowing Issue

Time:01-04

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 Prototypes 244 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

CodePudding user response:

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.

  • Related