Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The subtle difference between property assignment and definition #20

Open
Ayms opened this issue Sep 25, 2012 · 0 comments
Open

The subtle difference between property assignment and definition #20

Ayms opened this issue Sep 25, 2012 · 0 comments

Comments

@Ayms
Copy link

Ayms commented Sep 25, 2012

This is not exactly a regret but "how it works" or "why it is like this", trying to explain here the subtle difference between property assignment (=) and property definition (defineProperty), I hope this is not confusing (comments, corrections are welcome), apparently we need to get used to it :

var HTMLElement=function() {};

HTMLElement.prototype={
    get innerHTML() {return this.html_},
    set innerHTML(val) {this.html_=val},
    a: 'a'
};

var DIV=new HTMLElement();

DIV.innerHTML='c';
// Assignment operator "=", called as '[[Put]' below.

// If the property (own or inherited) does exist, is not an accessor and is 
// allowed to be modified, this creates a new own property 'innerHTML' 
// (if the property is inherited) or modifies the existing one.

// If the property does not exist, this creates a new own property 'innerHTML'.

// If the property is an accessor, this does trigger the accessor 
// (our case here).

console.log(DIV.innerHTML); //c
// OK, normal

Object.defineProperty(DIV,'innerHTML',{value:'b',writable : true,enumerable : true,configurable : true});
// Called as '[[DefineOwnProperty]]' below.

// This does define or modify a new 'innerHTML' own property that will 
// be returned prior to the inherited one (if it exists, our case here).

console.log(DIV.innerHTML); //b
// OK, so what ?
// Now consider for example http://wiki.ecmascript.org/doku.php?id=strawman:object_extension_literals
// To make it short the proposal is about extending an object literal :
// DIV.{width:'100px',height:'100px'}
// Surprisingly, the proposal does allow to do :
// DIV.{width='100px',height='100px'}
// the difference is that ':' stands for [[DefineOwnProperty]]
// and '=' for [[Put]]
// OK, surprising, but so what ? (again)
// Now consider that while coding, you might do :
// DIV.{innerHTML:'my html'}
// This will not have the effect you could expect, but just create a new 
// 'innerHTML' own property, therefore your div will not contain 'my html'
// Instead, you should have written :
// DIV.{innerHTML='my html'}

delete DIV.innerHTML;
// Delete the own property

console.log(DIV.innerHTML); // c
// Returns the inherited one

//Other example
console.log(DIV.a); //a
// Inherited property

DIV.a='b';

console.log(DIV.a); //b
// New own property

Object.defineProperty(DIV,'a',{value:'c',writable : true,enumerable : true,configurable : true});
// Modify the own property

console.log(DIV.a); //c

delete DIV.a;
// Delete the own property

console.log(DIV.a); //a
// Returns the inherited property

Maybe this sentence from Brendan Eich can summarize what is happening : "There really is a difference between assigning and defining in JS. Assigning runs setters, even inherited ones. Defining overrides or shadows."

Other examples can be found here : http://wiki.ecmascript.org/doku.php?id=strawman:define_properties_operator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant