Skip to content

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

Closed
@justinbmeyer

Description

@justinbmeyer

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions