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

Formalize .serialize(), .get(), hasOwnProperty, getOwnPropertyNames, .keys, etc ~21 #63

Closed
justinbmeyer opened this issue Sep 2, 2016 · 2 comments

Comments

@justinbmeyer
Copy link
Contributor

justinbmeyer commented Sep 2, 2016

From: canjs/canjs#2441

This proposal seeks to formalize the behavior of "looping" DefineMap methods and JavaScript functions and statements in relationship to the serialize, get and a new enumerable behavior.

Methods, functions, and statements

This proposal attempts to define the behavior of the following DefineMap methods, JavaScript functions, and JavaScript statements:

  • .get() - gets a non-observable representation of this map.
  • .serialize() - gets the POJO form of this map.
  • for...in - Can control in limited fashion.
  • Object.keys()
  • .hasOwnProperty()
  • .getOwnPropertyNames()
  • in operator

Note that JavaScript does not provide a mechanism to control the following behaviors:

  • Object.keys() - Would need [OwnPropertyKeys] symbol here.
  • .hasOwnProperty() - Would need [OwnPropertyKeys] symbol.
  • .getOwnPropertyNames() - Would need [OwnPropertyKeys] symbol.

In these cases, this proposal provides a desired behavior. The actual behavior will probably not work that way and a can-define alternative will need to exist.

for...of can be controlled with Symbol.iterator.

define behaviors

I propose two behaviors for controlling the previously listed methods, functions, and statements.

  • enumerable Boolean - true if the property is enumerable, false if otherwise. getters are enumerable: false by default, all other properties are enumerable: true by default.
  • serialize Boolean | function() - Controls the behavior of only serialize, overwrites the behavior of enumerable.

Furthermore, all core JavaScript functions and statements should follow the .get() behavior:

  • for...in - Same as for(var prop in map.get())
  • Object.keys() - Same as Object.keys( map.get() )
  • .hasOwnProperty() - Same as map.get().hasOwnProperty( propName )
  • .getOwnPropertyNames() - Same as map.get().getOwnPropertyNames()
  • in operator - Same as prop in map.get()

Examples

enumerable: undefined

enumerable: undefined

Type = DefineMap.extend({ prop: {} })

var map = new Type({prop: "VALUE"});
.get() //-> {prop: "VALUE"}
.serialize() //-> {prop: "VALUE"};

enumerable: undefined, serialize: false for #100

Type = DefineMap.extend({ prop: {serialize: false} })

var map = new Type({prop: "VALUE"});
.get() //-> {prop: "VALUE"}
.serialize() //-> {};

enumerable: false

enumerable: false

Type = DefineMap.extend({ prop: {enumerable: false} })

var map = new Type({prop: "VALUE"});
.get() //-> {}
.serialize() //-> {};

enumerable: false, serialize: true

Type = DefineMap.extend({ prop: {serialize: true, enumerable: false} })

var map = new Type({prop: "VALUE"});
.get() //-> {}
.serialize() //-> {prop: "VALUE"};

enumerable: true

enumerable: true

Type = DefineMap.extend({ prop: {enumerable: true} })

var map = new Type({prop: "VALUE"});
.get() //-> {prop: "VALUE"}
.serialize() //-> {prop: "VALUE"};

enumerable: true, serialize: false

Type = DefineMap.extend({ prop: {serialize: false, enumerable: true} })

var map = new Type({prop: "VALUE"});
.get() //-> {prop: "VALUE"}
.serialize() //-> {};

Big example

propA: {enumerable: undefined, serialize: undefined},              //-> get, serialize
propB: {enumerable: undefined, serialize: undefined, get: getter} //-> !get, !serialize

propA: {enumerable: undefined, serialize: true}              //-> get, serialize
propB: {enumerable: undefined, serialize: true, get: getter} //-> !get, serialize

propA: {enumerable: undefined, serialize: false}              //-> get, !serialize
propB: {enumerable: undefined, serialize: false, get: getter} //-> !get, !serialize

propA: {enumerable: true, serialize: undefined}              //-> get, serialize
propB: {enumerable: true, serialize: undefined, get: getter} //-> get, serialize
propB: {enumerable: true, serialize: true, get: getter}      //-> get, serialize
propB: {enumerable: true, serialize: true}                   //-> get, serialize

propA: {enumerable: false, serialize: undefined}              //-> !get, !serialize
propB: {enumerable: false, serialize: undefined, get: getter} //-> !get, !serialize
propB: {enumerable: false, serialize: true, get: getter}      //-> !get, serialize
propB: {enumerable: false, serialize: true}                   //-> !get, serialize
@justinbmeyer
Copy link
Contributor Author

Related: #13

@justinbmeyer
Copy link
Contributor Author

justinbmeyer commented Dec 16, 2016

How define could be used to support for ... in loops currently:

var definition = {
  get prop(){},
};

var MyType = function(props){
  var obj  = define( props, definition );
  return obj;
}

new MyType();

for(var prop in obj ) {}

}

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

No branches or pull requests

2 participants