简体   繁体   中英

Property Shadowing Issue

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM