{"action":"created","issue":{"url":"https://api.github.com/repos/jashkenas/backbone/issues/3560","labels_url":"https://api.github.com/repos/jashkenas/backbone/issues/3560/labels{/name}","comments_url":"https://api.github.com/repos/jashkenas/backbone/issues/3560/comments","events_url":"https://api.github.com/repos/jashkenas/backbone/issues/3560/events","html_url":"https://github.com/jashkenas/backbone/issues/3560","id":66908876,"number":3560,"title":"Backbone and ES6 Classes","user":{"login":"benmccormick","id":1899941,"avatar_url":"https://avatars.githubusercontent.com/u/1899941?v=3","gravatar_id":"","url":"https://api.github.com/users/benmccormick","html_url":"https://github.com/benmccormick","followers_url":"https://api.github.com/users/benmccormick/followers","following_url":"https://api.github.com/users/benmccormick/following{/other_user}","gists_url":"https://api.github.com/users/benmccormick/gists{/gist_id}","starred_url":"https://api.github.com/users/benmccormick/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/benmccormick/subscriptions","organizations_url":"https://api.github.com/users/benmccormick/orgs","repos_url":"https://api.github.com/users/benmccormick/repos","events_url":"https://api.github.com/users/benmccormick/events{/privacy}","received_events_url":"https://api.github.com/users/benmccormick/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/jashkenas/backbone/labels/change","name":"change","color":"27823f"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":43,"created_at":"2015-04-07T14:59:42Z","updated_at":"2015-09-21T15:28:45Z","closed_at":null,"body":"With the final changes to the ES6 class spec (details [here](http://www.2ality.com/2015/02/es6-classes-final.html)), it's no longer possible to use ES6 classes with Backbone without making significant compromises in terms of syntax.  I've written a full description of the situation [here](http://benmccormick.org/2015/04/07/es6-classes-and-backbone-js/) (make sure to click through to the comments at the bottom for an additional mitigating option), but essentially there is no way to add properties to an instance of a subclass prior to the subclasses parents constructor being run.\r\n\r\nSo this:\r\n\r\n```javascript\r\nclass DocumentRow extends Backbone.View {\r\n\r\n    constructor() {\r\n        this.tagName =  \"li\";\r\n        this.className = \"document-row\";\r\n        this.events = {\r\n            \"click .icon\":          \"open\",\r\n            \"click .button.edit\":   \"openEditDialog\",\r\n            \"click .button.delete\": \"destroy\"\r\n        };\r\n        super();\r\n    }\r\n\r\n    initialize() {\r\n        this.listenTo(this.model, \"change\", this.render);\r\n    }\r\n\r\n    render() {\r\n        //...\r\n    }\r\n}\r\n```\r\n\r\nis no longer valid in the final ES6 spec.  Instead you effectively have 3 (not very appealing) options if you want to try to make this work:\r\n\r\n<h2 id=\"methods\">Attach all properties as functions</h2>\r\n\r\nBackbone allows this, but it feels dumb to write something like this: \r\n\r\n```javascript\r\nclass DocumentRow extends Backbone.View {\r\n\r\n    tagName() { return \"li\"; }\r\n\r\n    className() { return \"document-row\";}\r\n\r\n    events() {\r\n        return {\r\n            \"click .icon\":          \"open\",\r\n            \"click .button.edit\":   \"openEditDialog\",\r\n            \"click .button.delete\": \"destroy\"\r\n        };\r\n    }\r\n\r\n    initialize() {\r\n        this.listenTo(this.model, \"change\", this.render);\r\n    }\r\n\r\n    render() {\r\n        //...\r\n    }\r\n}\r\n```\r\n\r\ncompared to the current extends syntax\r\n\r\n## Run the constructor twice\r\n\r\nI don't view this as a real option due to the issues it would cause running initialize a second time with different cids, etc.\r\n\r\n<h2 id=\"default-options\">Pass all properties as default options to the superclass constructor</h2>\r\n\r\nThis was suggested by a commenter on my blog and is probably the most practical current option.  It looks something like this:\r\n\r\n```javascript\r\nclass MyView extends Backbone.View {\r\n  constructor(options) {\r\n    _.defaults(options, {\r\n      // These options are assigned to the instance by Backbone\r\n      tagName: 'li',\r\n      className: 'document-row',\r\n      events: {\r\n        \"click .icon\": \"open\",\r\n        \"click .button.edit\": \"openEditDialog\",\r\n        \"click .button.delete\": \"destroy\"\r\n      },\r\n      // This option I'll have to assign to the instance myself\r\n      foo: 'bar'\r\n    });\r\n\r\n\r\n    super(options);\r\n\r\n\r\n    this.foo = options.foo;\r\n  }\r\n}\r\n```\r\n\r\nSince all of these current options involve clear compromises relative to the current Backbone extends syntax, it would be wonderful if a better solution could be developed.  I'm not totally sure what this should look like, but one idea that came to mind while I did the writeup for my blog was the addition of a \"properties\" function that would output a hash of properties. The constructor could then run that function and add them to the instance prior to the other processing done by the constructor.  "},"comment":{"url":"https://api.github.com/repos/jashkenas/backbone/issues/comments/142015454","html_url":"https://github.com/jashkenas/backbone/issues/3560#issuecomment-142015454","issue_url":"https://api.github.com/repos/jashkenas/backbone/issues/3560","id":142015454,"user":{"login":"just-boris","id":812240,"avatar_url":"https://avatars.githubusercontent.com/u/812240?v=3","gravatar_id":"","url":"https://api.github.com/users/just-boris","html_url":"https://github.com/just-boris","followers_url":"https://api.github.com/users/just-boris/followers","following_url":"https://api.github.com/users/just-boris/following{/other_user}","gists_url":"https://api.github.com/users/just-boris/gists{/gist_id}","starred_url":"https://api.github.com/users/just-boris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/just-boris/subscriptions","organizations_url":"https://api.github.com/users/just-boris/orgs","repos_url":"https://api.github.com/users/just-boris/repos","events_url":"https://api.github.com/users/just-boris/events{/privacy}","received_events_url":"https://api.github.com/users/just-boris/received_events","type":"User","site_admin":false},"created_at":"2015-09-21T15:28:45Z","updated_at":"2015-09-21T15:28:45Z","body":"@benmccormick https://github.com/wycats/javascript-decorators already has [extra definition regarding property initializers]( https://github.com/wycats/javascript-decorators/blob/master/INITIALIZER_INTEROP.md).\r\n\r\nThe main concern there that property initializers is a usual descriptor, as well as class methods, so decorators can wrap them as well. I don't see reasons to worry, while spec in that section remains unchanged"}}