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

Add getter/setter support to extend method #3483

Closed
jamiebuilds opened this issue Feb 9, 2015 · 12 comments
Closed

Add getter/setter support to extend method #3483

jamiebuilds opened this issue Feb 9, 2015 · 12 comments

Comments

@jamiebuilds
Copy link

Since getters/setters are supported IE9+ and will be much more prevalent with ES6 it'd be nice if Backbone's extend method supported them.

var Person = Backbone.Model.extend({
  get fullName() {
    return this.get('firstName') + ' ' + this.get('lastName');
  }
});

var elonMusk = new Person({
  firstName: 'Elon', 
  lastName: 'Musk'
});

console.log(person.fullName); // >> Elon Musk

Right now this would result in undefined is not a function because using _.extend is calling the getter.

@akre54
Copy link
Collaborator

akre54 commented Feb 9, 2015

Is there any reason that couldn't be better written as person.fullName() so you know it's a function call?

Using getters and setters are for the most part a bad idea in JS, and they go against one of the core ideas of Backbone Models. I doubt you'll see support added anytime soon.

@jamiebuilds
Copy link
Author

More than anything this would be partially aligned with the new class syntax. There are no property initializers in the class syntax or even any spec for them yet, so interop will be an issue.

they go against one of the core ideas of Backbone Models.

What core idea is that?

Also getters are a partial solution to an existing problem in Backbone.Collection with model.idAttribute.

@jamiebuilds
Copy link
Author

Spent a few minutes trying to make a jsperf with different solutions:
http://jsperf.com/backbone-extend-with-define-property

@akre54
Copy link
Collaborator

akre54 commented Feb 9, 2015

What core idea is that?

The idea that setting and retrieving a property on an object should be transparent and logical to reason about. You should always know that obj.prop = val never does anything other than setting that property value (ditto for retrieval), while we should use functions to handle things like computed properties and change events. That's the main reason for the get and set wrapper methods around attributes in the first place.

Also getters are a partial solution to an existing problem in Backbone.Collection with model.idAttribute.

Any reason the current _.result wrapper doesn't work for this? idAttribute can either be a primitive or a function. This is also being fixed with modelId.

@jamiebuilds
Copy link
Author

Sorry I should've linked to the issue I was speaking about: #3408

I'm bringing this up mainly because Backbone's class syntax is largely already compatible with the ES class syntax, and it seems only reasonable they be compatible considering the added support for coffeescript.

@akre54
Copy link
Collaborator

akre54 commented Feb 9, 2015

CoffeeScript doesn't support setters and getters largely for the same reasons (look into issues there for some background, starting with jashkenas/coffeescript#2902). They shouldn't be a roadblock to supporting Backbone objects as classes.

Sorry I should've linked to the issue I was speaking about: #3408

Remind me? I'm straining to see the connection off the bat.

Besides, any changes to extend would have to be done in _.extend, not here. Closing as a wontfix.

@jamiebuilds
Copy link
Author

CoffeeScript doesn't support setters and getters largely for the same reasons

I wasn't speaking about getters/setters, I was speaking about how Backbone added __super__ for interop with CoffeeScript, and how it only makes sense for it to support ES6 classes in the same manner.

Remind me? I'm straining to see the connection off the bat.

Collection.extend({
  model: function() { return Model }
});
//
collection.modelId(model); // 'id' regardless if that's correct or not.
Collection.extend({
  get model() { return Model }
});
//
collection.modelId(model); // correct for *some* of the common cases.

Besides, any changes to extend would have to be done in _.extend, not here. Closing as a wontfix.

That's definitely not the right place for this change, if anything it would be in the new _.assign method. But it makes much more sense for it to be supported here IMO.

Also, before this issue gets closed and forgotten about I would like to address why it's okay for Backbone's extend to have the interop issues with ES classes but not CoffeeScript classes.

@akre54
Copy link
Collaborator

akre54 commented Feb 10, 2015

Well seeing as IE Tech Preview is the only browser with even remotely decent support of class (even Traceur and 6to5 don't yet convert extends), we're a ways off from this even being necessary. That aside Backbone isn't going to go out of its way to break backwards compatibility just to support a feature that isn't a great idea to begin with.

@jamiebuilds
Copy link
Author

even Traceur and 6to5 don't yet convert extends

They both do actually, they just require support for __proto__ for static properties which is widely supported.

Also there is no reason backwords-compatibility needs to be broken, it could even be made faster if it selectively used Object.setPrototypeOf where available.

@jashkenas
Copy link
Owner

@thejameskyle Want to turn this into a PR instead of an issue? It's worth looking at.

@jamiebuilds
Copy link
Author

Sure, I'll do that

@nicolas-zozol
Copy link

Is it on the way ? Have you a gist or something about it ? I'd like to take a shot.

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

4 participants