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

Protected Method Support? #16

Open
oyiadom opened this issue Jul 22, 2014 · 1 comment
Open

Protected Method Support? #16

oyiadom opened this issue Jul 22, 2014 · 1 comment

Comments

@oyiadom
Copy link

oyiadom commented Jul 22, 2014

Protected Method Support?

Does Fiber support protected methods and properties? In the example below, I would like the constructor in the base class to be able to call methods that it has defined and shared with all child classes (e.g. paintHtml), as well as methods that child classes have defined or overridden (e.g. buildHtml).

var my = my || {};

my.Base = Fiber.extend(function () {
    return {
        init: function (options) {
            this.html = "";

            this.buildHtml = function () {
                // This method will almost always be overridden by child classes
            };

            this.paintHtml = function () {
                this.containerEl.html(this.html);
            };

            /******************************************************************/
            /* Begin Initialization */

            var containerDomId = options.containerDomId || "";
            this.containerEl = $("#" + containerDomId);
            this.buildHtml();
            this.paintHtml();

            /* End Initialization */
            /******************************************************************/
        }
    };
});


my.Child1 = my.Base.extend(function (BaseClass) {
    return {
        init: function (options) {
            this.buildHtml = function () {
                this.html = "HTML5 User Interface for the Child1 component";
            };


            /******************************************************************/
            /* Begin Initialization */

            BaseClass.init.call(this, options); // calls the buildHtml() method defined in this class and the paintHtml() method defined in the base class

            /* End Initialization */
            /******************************************************************/
        }
    };
});


my.Child2 = my.Base.extend(function (BaseClass) {
    return {
        init: function (options) {
            this.buildHtml = function () {
                this.html = "HTML5 User Interface for the Child2 component";
            };


            /******************************************************************/
            /* Begin Initialization */

            BaseClass.init.call(this, options); // calls the buildHtml() method defined in this class and the paintHtml() method defined in the base class

            /* End Initialization */
            /******************************************************************/
        }
    };
});
@krisk
Copy link
Contributor

krisk commented Jul 29, 2014

@Pursuittech, the short answer is no, Fiber (and native JavaScript in general) cannot quickly do what (I think) you'd like it to do, at least not without introducing some nifty and intricate tricks.

Consider the following code (a simplified version of your example):

var Parent = Fiber.extend(function() {
  return {
    init: function() {
      this.greet = function() {
        console.log('Parent');
      }
      this.method();
    }
  };
});

From above ,Child is a subclass of Parent. In Parent::init there is greet (often called a privileged method. In the intereset of nomenclature we won't call them protected, as JavaScript doesn't really have that notion). Note that this method is not part of the prototype, but is on the instance itself. Now, consider the following subclass and instantiation:

var Child = Parent.extend(function(base) {
  return {
    init: function() {
      this.greet = function() {
        console.log('Child');
      };
      // Call the base class `init`... but doing this will resut
      // in the current `greet` function to be overidden by the base class!
      base.init.call(this);
    }
  };
});

var c = new Child();

// Output:
//   Parent

By creating an instance of Child, since its init function calls the base class init, the instance's greet function is overridden by the parent's own greet function. Ergo, the output will be that of the parent.

Frankly (in my opinion at least), from a design perspective, instance functions set within init should seldom be overridden. Specifically, if you find yourself needing to override functions set on the instance, perhaps they should be placed on the prototype instead.

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

No branches or pull requests

2 participants