4

I have a few related backbone Views:

First:

App.Views.TreeGrowthBase = App.Views.TreeGrowthBase.extend({
  events: {
    'submit form': 'submitForm',
...

and then in the same file:

submitForm: function(e) {
    e.preventDefault();

and elsewhere in the app:

App.Views.WineTreeGrowthBase = App.Views.TreeGrowthBase.extend({
  submitForm(event) {
    event.preventDefault();

My questions: In that last piece of code... what is the syntax:

submitForm(event) {
    event.preventDefault();

Is that a method call? Defining a method? Where are the colons?

Which one takes precedence? I imagine the child view's submitForm method definition takes place... if it is a method definition?

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Jwan622
  • 11,015
  • 21
  • 88
  • 181

1 Answers1

4

Method definition shorthand

submitForm(event) {
    event.preventDefault();

This is the method definition shorthand new in ES6 (ECMAScript 2015).

It's equivalent to

submitForm: function submitForm(event) {
    event.preventDefault();

The shorthand syntax uses named function instead of anonymous functions (as in foo: function() {}). Named functions can be called from the function body (this is impossible for anonymous function as there is no identifier to refer to). For more details, see function.

and works in browser which have the new features available (like other than IE).

Overriding functions

Any method overridden in a child of a Backbone class (the result of the extend function) takes precedence on the parent function. If you would like to call the parent function, it's still possible:

submitForm: function(event) {
    // Using the Backbone '__super__'
    ThisClass.__super__.submitForm.apply(this, arguments);
    // Or the JavaScript preferred way
    ParentClass.prototype.submitForm.apply(this, arguments);
    event.preventDefault();
}

This is not specific to Backbone. It's the normal behavior of the prototype chain. Backbone just wraps the complexity in a simple extend function.

See this in-depth answer for more info.


Do not use this.constructor.__super__ because it's not guarantied to be the actual class and it could be the constructor of the child class, causing a call stack overflow. Favor MyCurrentClass.__super__, it's explicit and close the door to potential extending problems.

Community
  • 1
  • 1
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • It has to be `this.constructor.__super__` and it can't be `this.__super__`? – Jwan622 Dec 19 '16 at 23:20
  • 1
    @Jwan622 It's because `this.constructor === ChildClass` and `this.constructor.__super__ === ChildClass.__super__` and `ChildClass.__super__ === ParentClass.prototype`. I like `this.construtor.__super__` because it removes the hard-coded name of the parent from the function and could potentially avoid hard to track bugs when changing the parent from which the child extends. – Emile Bergeron Dec 19 '16 at 23:34
  • 1
    It's clearer to see when looking at the source of Backbone's [`.extend` function](https://github.com/jashkenas/backbone/blob/7da4ed73e7402baf614a50a6551d47ace68b5239/backbone.js#L1978-L2007). – Emile Bergeron Dec 19 '16 at 23:35
  • @Jwan622 I updated my answer to inform you and readers about the potential problems of `this.constructor.__super__`. – Emile Bergeron Jan 12 '17 at 20:49