JavaScript GUI library idea

Discussion in 'Javascript' started by petermichaux@gmail.com, Mar 25, 2006.

  1. Guest

    Hi,

    I've been asking questions about library design over the last week and
    would like to get feedback on my overall idea for a JavaScript GUI
    library. I need a nice GUI library so there is a good chance I will
    write this as I need new widgets. I haven't found anything like this
    and I'm surprised/disapointed this doesn't already exist. My library
    prototype works nicely. I think parts of these ideas are not commonly
    used for JavaScript library development and before I dive in too deeply
    any experienced advice might make my efforts a lot better.

    While trying to develop a rich GUI for a web app backend I started
    needing a large set of GUI widgets that behaved and were coded
    similarly. Things like flyout menus, drop down menubars, tree menus,
    adjustable table widths, spinners...all the things that are in Java
    Swing or other GUI widget libraries. Yes I know all of these things
    exist individually as JavaScripts but I would like to build a library
    that uses a class hierarchy structure and inheritance to take advantage
    of all the nice OOP ideas of encapsulation etc. Certainly this library
    will be different than a desktop app GUI library since HTML, CSS and
    the browser already provide a lot of what is needed (<ul>'s for menus,
    <table> for tables, all sorts of font display stuff, some form
    elements). In JavaScript we are adding functionality on top of what the
    browser already gives us.

    This could end up being a big library but if each class is in it's own
    file and the class hierarchy is known then people could string together
    only the pieces they need. I would like a develop a way to automate
    this step. Something like compiling one JavaScript file with all you
    need for your page from the big library.

    For JavaScript inheritance I want to use these ideas
    http://www.kevlindev.com/tutorials/javascript/inheritance/

    I will use one namespace for everything. My library will not interfere
    with other libraries.

    No direct extending of Function or Array and breaking stuff like
    Prototype.js does. Instead I will subclass these as necessary and
    extend in the subclass. Directly extending Function or Array would not
    go well with my namespace requirement.

    No monolithic support script like Prototype.js that tries to turn
    JavaScript into Ruby or Python or whatever. Just JavaScript.

    All machinery CSS (the stuff that makes the items work eg. display:none
    or display:block) inserted with JavaScript and the DOM into the tag's
    style elements so that they have specificity 1,0,0,0. This way a user
    of the library cannot override without using !important in their CSS
    rules.

    Separation of machinery CSS and the rest of the JavaScript with the
    idea that every change to a DOM element's style attribute is and
    "effect". So all the effects will be tucked away nicely in a single
    Effects object. This one object will be the only place to look for
    browser specific hacks. Hacks can be reused by composite effects.

    A default set of CSS files for the pretty stuff that can be overridden
    as desired by the library user in their own style sheets. This has
    lowest possible specificity so these rules are easily overridden.

    Two library interfaces. One advanced interface that allows access to
    widget options through a single line of JavaScript per widget.

    <head>
    <script type="text/javascript" src="seriousWidgets.js"></script>
    </head>
    <body>
    <ul id="myMenuBar">
    <li>item 1<li>
    <li>item 2<li>
    <ul>
    <script>
    var my_menu_bar = new
    Serious.MenuBar(document.getElementById("myMenuBar"),
    {option1:value1,
    option2:value2});
    </script>
    </body>

    A second interface, a completely non-obtrusive facade for those who
    want to avoid JavaScript at all costs and have widgets that function in
    standard ways. Appearance still easily overridden with CSS.

    <head>
    <script type="text/javascript" src="easyWidgets.js"></script>
    </head>
    <body>
    <ul class="easyMenuBar">
    <li>item 1<li>
    <li>item 2<li>
    <ul>
    </body>

    Any thoughts, ideas, cautions or warnings appreciated.

    Thanks,
    Peter
    , Mar 25, 2006
    #1
    1. Advertising

  2. wrote:

    > I've been asking questions about library design over the last week and
    > would like to get feedback on my overall idea for a JavaScript GUI
    > library. I need a nice GUI library so there is a good chance I will
    > write this as I need new widgets. I haven't found anything like this
    > and I'm surprised/disapointed this doesn't already exist. My library
    > prototype works nicely. I think parts of these ideas are not commonly
    > used for JavaScript library development and before I dive in too deeply
    > any experienced advice might make my efforts a lot better.


    It does not work without client-side script support which is its major flaw.

    > While trying to develop a rich GUI for a web app backend I started
    > needing a large set of GUI widgets that behaved and were coded
    > similarly. Things like flyout menus, drop down menubars, tree menus,
    > adjustable table widths, spinners...all the things that are in Java
    > Swing or other GUI widget libraries.


    XUL and HTA exist.

    > Yes I know all of these things exist individually as JavaScripts but I
    > would like to build a library that uses a class hierarchy structure and
    > inheritance to take advantage of all the nice OOP ideas of encapsulation
    > etc.


    Unless .NET or SpiderMonkey 2.0 is a requirement, you can forget about
    classes.

    <URL:http://javascript.crockford.com/inheritance.html>

    > Certainly this library will be different than a desktop app GUI library
    > since HTML, CSS and the browser already provide a lot of what is needed
    > (<ul>'s for menus, <table> for tables, all sorts of font display stuff,
    > some form elements).


    You are misunderstanding a Web browser as an application platform.

    > In JavaScript we are adding functionality on top of what the browser
    > already gives us.


    Which is why graceful degradation is possible.

    > [...]
    > For JavaScript inheritance I want to use these ideas
    > http://www.kevlindev.com/tutorials/javascript/inheritance/


    Factually wrong.

    > I will use one namespace for everything.


    Unless .NET or SpiderMonkey 2.0 is a requirement, you can forget about
    namespaces.

    > My library will not interfere with other libraries.


    You cannot ensure that.

    > [...]
    > All machinery CSS (the stuff that makes the items work eg. display:none
    > or display:block) inserted with JavaScript and the DOM into the tag's
    > style elements so that they have specificity 1,0,0,0. This way a user
    > of the library cannot override without using !important in their CSS
    > rules.
    > [...]
    > <head>
    > <script type="text/javascript" src="seriousWidgets.js"></script>
    > </head>
    > <body>
    > <ul id="myMenuBar">
    > <li>item 1<li>
    > <li>item 2<li>
    > <ul>
    > <script>
    > var my_menu_bar = new
    > Serious.MenuBar(document.getElementById("myMenuBar"),
    > {option1:value1,
    > option2:value2});
    > </script>
    > </body>


    This feature, which does not allow for graceful degradation, is required
    only for current IEeeks, and hopefully not for its future versions. CSS
    can do the work in all other UAs, and allows for graceful degradation.

    > A second interface, a completely non-obtrusive facade for those who
    > want to avoid JavaScript at all costs and have widgets that function in
    > standard ways. Appearance still easily overridden with CSS.


    Nonsense. Both birds can all be killed with one stone.

    > Any thoughts, ideas, cautions or warnings appreciated.


    [x] done


    PointedEars
    Thomas 'PointedEars' Lahn, Mar 25, 2006
    #2
    1. Advertising

  3. Guest

    PointedEars,

    Thanks for the reply. I'm interested in a bit of expansion on the
    things you mentioned.


    Thomas 'PointedEars' Lahn wrote:
    > Peter Michaux wrote:


    > It does not work without client-side script support which is its major flaw.


    I'm requiring the user has a browser released in the last couple years
    and have turned javascript on. Is that unreasonable for a javascript
    library? Do you consider all of your scripts as "majorly flawed"?
    Perhaps I missed your point.

    > XUL and HTA exist.


    These look specific to Mozilla and IE, respectively. If that is true it
    doesn't cut it for what I want to do.

    > <URL:http://javascript.crockford.com/inheritance.html>


    Thanks for the link.

    > > For JavaScript inheritance I want to use these ideas
    > > http://www.kevlindev.com/tutorials/javascript/inheritance/

    >
    > Factually wrong.


    Why is it factually wrong? I am very interested in justified criticisms
    of this method.

    > Unless .NET or SpiderMonkey 2.0 is a requirement, you can forget about
    > namespaces.


    I mean simulated namespaces like
    http://blog.dreamprojections.com/archive/2004/12/27/450.aspx

    > > [...]
    > > All machinery CSS (the stuff that makes the items work eg. display:none
    > > or display:block) inserted with JavaScript and the DOM into the tag's
    > > style elements so that they have specificity 1,0,0,0. This way a user
    > > of the library cannot override without using !important in their CSS
    > > rules.
    > > [...]
    > > <head>
    > > <script type="text/javascript" src="seriousWidgets.js"></script>
    > > </head>
    > > <body>
    > > <ul id="myMenuBar">
    > > <li>item 1<li>
    > > <li>item 2<li>
    > > <ul>
    > > <script>
    > > var my_menu_bar = new
    > > Serious.MenuBar(document.getElementById("myMenuBar"),
    > > {option1:value1,
    > > option2:value2});
    > > </script>
    > > </body>

    >
    > This feature, which does not allow for graceful degradation, is required
    > only for current IEeeks, and hopefully not for its future versions. CSS
    > can do the work in all other UAs, and allows for graceful degradation.


    "IEeeks"? Don know that one.

    Why does this code not allow for graceful degradation?

    > > A second interface, a completely non-obtrusive facade for those who
    > > want to avoid JavaScript at all costs and have widgets that function in
    > > standard ways. Appearance still easily overridden with CSS.

    >
    > Nonsense. Both birds can all be killed with one stone.


    The reason for the two interfaces is efficiency. If a user will not use
    the easyWidgets interface then there is no point in having the
    javascript search through the html for tags with className including
    "easyMenuBar" etc.

    Thanks,
    Peter
    , Mar 25, 2006
    #3
  4. wrote:

    > Thomas 'PointedEars' Lahn wrote:
    >> Peter Michaux wrote:
    >> It does not work without client-side script support which is its major
    >> flaw.

    >
    > I'm requiring the user has a browser released in the last couple years
    > and have turned javascript on. Is that unreasonable for a javascript
    > library? Do you consider all of your scripts as "majorly flawed"?
    > Perhaps I missed your point.


    Requiring a recent browser, and requiring it to have client-side script
    support enabled are two different things. Especially with IEeek (see
    below) and RadioActiveX (I think you get the idea). We really discussed
    this ad nauseam here before. Search the archives about that, and search
    them for UI library discussions. You are by far not the first person
    (here) who thought of this, tried it and, inevitably, failed. Reading that
    will probably help you investing your time in something that makes more
    sense.

    >> > For JavaScript inheritance I want to use these ideas
    >> > http://www.kevlindev.com/tutorials/javascript/inheritance/

    >>
    >> Factually wrong.

    >
    > Why is it factually wrong? I am very interested in justified criticisms
    > of this method.


    For example, there are no classes and no subclasses in the languages
    supported by the execution environments you target. And the init()
    approach, probably copied without minimum clue from the Prototype junk
    code, is nonsense. The language already has constructors for that.

    >> Unless .NET or SpiderMonkey 2.0 is a requirement, you can forget about
    >> namespaces.

    >
    > I mean simulated namespaces like
    > http://blog.dreamprojections.com/archive/2004/12/27/450.aspx


    As I said, those are not namespaces. Using a user-defined container
    object for other user-defined objects is a better approach than declaring
    everything global, that is for sure. But there is no guarantee that there
    will be no interference with other, unknown libraries. The dynamic nature
    of ECMAScript 1-3 implementations does not allow for such restrictions.

    >> > [...]
    >> > All machinery CSS (the stuff that makes the items work eg. display:none
    >> > or display:block) inserted with JavaScript and the DOM into the tag's
    >> > style elements so that they have specificity 1,0,0,0. This way a user
    >> > of the library cannot override without using !important in their CSS
    >> > rules.
    >> > [...]
    >> > <head>
    >> > <script type="text/javascript" src="seriousWidgets.js"></script>
    >> > </head>
    >> > <body>
    >> > <ul id="myMenuBar">
    >> > <li>item 1<li>
    >> > <li>item 2<li>
    >> > <ul>
    >> > <script>
    >> > var my_menu_bar = new
    >> > Serious.MenuBar(document.getElementById("myMenuBar"),
    >> > {option1:value1,
    >> > option2:value2});
    >> > </script>
    >> > </body>

    >>
    >> This feature, which does not allow for graceful degradation, is required
    >> only for current IEeeks, and hopefully not for its future versions. CSS
    >> can do the work in all other UAs, and allows for graceful degradation.

    >
    > "IEeeks"? Don know that one.


    IEs. User agents based on Microsoft Internet Explorer. Its layout engine
    is this badly borken and its API is this flawed that some people, including
    me, tend to think "Eeek" when talking about developing for it. And since
    IE7 is not going to be released for Windows 2000 and earlier, it is
    probably going to stay that way.

    > Why does this code not allow for graceful degradation?


    Because there will be no menu without client-side script support.
    Which can be easily avoided with a design approach that took more
    consideration to develop.

    >> > A second interface, a completely non-obtrusive facade for those who
    >> > want to avoid JavaScript at all costs and have widgets that function in
    >> > standard ways. Appearance still easily overridden with CSS.

    >>
    >> Nonsense. Both birds can all be killed with one stone.

    >
    > The reason for the two interfaces is efficiency. If a user will not
    > use the easyWidgets interface then there is no point in having the
    > javascript search through the html for tags with className including
    > "easyMenuBar" etc.


    Efficiency and maintenance considerations are the reason why this should be
    done with one script version, if that. One version that uses client-side
    scripting only if necessary in the first place. It has been done before.

    And, reconsidering this, for more recent IE versions apparently it can
    be done without client-side scripting, too. The most recent and most
    convincing example posted here that I can remember is

    <URL:http://www.cssplay.co.uk/menus/dd_valid.html>


    HTH

    PointedEars
    Thomas 'PointedEars' Lahn, Mar 25, 2006
    #4
  5. Guest

    Thomas 'PointedEars' Lahn wrote:

    > Requiring a recent browser, and requiring it to have client-side script
    > support enabled are two different things. Especially with IEeek (see
    > below) and RadioActiveX (I think you get the idea). We really discussed
    > this ad nauseam here before. Search the archives about that, and search
    > them for UI library discussions.


    Unfortunately I did not have a fruitful search with those key words.


    > You are by far not the first person (here) who thought of this,
    > tried it and, inevitably, failed.


    Failed due to developing for a moving target of browser support?


    > Reading that will probably help you investing your time in
    > something that makes more sense.


    What would make more sense for a GUI widget library? Or do you think
    JavaScript GUI widgets are a waste of time?


    >>>> For JavaScript inheritance I want to use these ideas
    >>>> http://www.kevlindev.com/tutorials/javascript/inheritance/
    >>>
    >>> Factually wrong.

    >>
    >> Why is it factually wrong? I am very interested in justified criticisms
    >> of this method.

    >
    > For example, there are no classes and no subclasses in the languages
    > supported by the execution environments you target. And the init()
    > approach, probably copied without minimum clue from the Prototype junk
    > code, is nonsense. The language already has constructors for that.


    I've tried the method on this page. It works nicely. It seems very
    native JavaScript using prototype inheritance. I still don't understand
    what you object to in this method.


    >> Why does this code not allow for graceful degradation?

    >
    > Because there will be no menu without client-side script support.


    I'm developing for an environment with client-side script support. So
    that shouldn't be a problem. I get the feeling that you think using
    JavaScript is a bad idea.


    > Which can be easily avoided with a design approach that took more
    > consideration to develop.


    You mean there is always an alternative to using JavaScript that should
    be used instead for GUI widgets?

    By design approach do you mean graphic design? If so I can see your
    point for menus but not for all GUI widgets. I think that some widgets
    just need JavaScript (eg. a slider). If you mean JavaScript code design
    then I don't know what you mean.


    > And, reconsidering this, for more recent IE versions apparently it can
    > be done without client-side scripting, too. The most recent and most
    > convincing example posted here that I can remember is
    >
    > <URL:http://www.cssplay.co.uk/menus/dd_valid.html>


    Very interesting menu design. This seems to use a lot of comments in
    the html document. Since I'll be using/requiring JavaScript anyway I
    don't see the harm in using JavaScript to run the menus.


    Peter
    , Mar 26, 2006
    #5
  6. Randy Webb Guest

    said the following on 3/25/2006 8:30 PM:
    > Thomas 'PointedEars' Lahn wrote:
    >
    >> Requiring a recent browser, and requiring it to have client-side script
    >> support enabled are two different things. Especially with IEeek (see
    >> below) and RadioActiveX (I think you get the idea). We really discussed
    >> this ad nauseam here before. Search the archives about that, and search
    >> them for UI library discussions.

    >
    > Unfortunately I did not have a fruitful search with those key words.


    Welcome to comp.lang.javascript and Thomas. :-X

    >
    >> You are by far not the first person (here) who thought of this,
    >> tried it and, inevitably, failed.

    >
    > Failed due to developing for a moving target of browser support?


    Inevitable failure is always the result of scripting. It is, be default,
    part of it's nature.

    >
    >> Reading that will probably help you investing your time in
    >> something that makes more sense.

    >
    > What would make more sense for a GUI widget library? Or do you think
    > JavaScript GUI widgets are a waste of time?


    Thomas thinks that anything that wasn't his idea is a waste of time.

    >
    >>>>> For JavaScript inheritance I want to use these ideas
    >>>>> http://www.kevlindev.com/tutorials/javascript/inheritance/
    >>>> Factually wrong.
    >>> Why is it factually wrong? I am very interested in justified criticisms
    >>> of this method.

    >> For example, there are no classes and no subclasses in the languages
    >> supported by the execution environments you target. And the init()
    >> approach, probably copied without minimum clue from the Prototype junk
    >> code, is nonsense. The language already has constructors for that.

    >
    > I've tried the method on this page. It works nicely. It seems very
    > native JavaScript using prototype inheritance. I still don't understand
    > what you object to in this method.


    He seems to be stuck on your use of the word "classes" in Javascript. It
    doesn't have classes but you can come real close to emulating them.

    >>> Why does this code not allow for graceful degradation?

    >> Because there will be no menu without client-side script support.

    >
    > I'm developing for an environment with client-side script support. So
    > that shouldn't be a problem. I get the feeling that you think using
    > JavaScript is a bad idea.


    Again, meet Thomas. His ideas are not to help people but to merely point
    out any/all flaws in any idea that isn't his.

    >
    >> Which can be easily avoided with a design approach that took more
    >> consideration to develop.

    >
    > You mean there is always an alternative to using JavaScript that should
    > be used instead for GUI widgets?
    >
    > By design approach do you mean graphic design? If so I can see your
    > point for menus but not for all GUI widgets. I think that some widgets
    > just need JavaScript (eg. a slider). If you mean JavaScript code design
    > then I don't know what you mean.
    >
    >
    >> And, reconsidering this, for more recent IE versions apparently it can
    >> be done without client-side scripting, too. The most recent and most
    >> convincing example posted here that I can remember is
    >>
    >> <URL:http://www.cssplay.co.uk/menus/dd_valid.html>

    >
    > Very interesting menu design.


    Yes indeed.
    IE: Tools>Internet Options>Accessibility>Ignore X 3

    Menu looks nice then. But it's broken. So much for CSS degradation huh?

    And Firefox? Disable CSS via any of the many add-ons and that page
    becomes horrendous.

    My point? Anything can be broken....

    > This seems to use a lot of comments in the html document.
    > Since I'll be using/requiring JavaScript anyway I don't see
    > the harm in using JavaScript to run the menus.


    There isn't. Contrary to most people here's belief the trend on the web
    is *towards* scripting, not away from it.

    "Graceful Degradation" is one of those buzz terms people like to use in
    order to argue against anything they don't agree with.

    --
    Randy
    comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
    Randy Webb, Mar 26, 2006
    #6
  7. writes:

    > I'm developing for an environment with client-side script support.


    That's the problem. In this group, the default assumption, unless
    something else is said, is that the scripting is for web pages
    for the internet. The internet as a whole is not an environment
    where client-side script support can be assumed. The percentages
    of people browsing without Javascript varies. TheCounter.com has
    had numbers up to 9% late last year, but is currently at 3%.

    > So that shouldn't be a problem. I get the feeling that you think
    > using JavaScript is a bad idea.


    Javascript is a great idea for *enhancing* pages, but if the page
    *depends* on Javascript, then there are people who cannot use it at
    all. Graceful degredation would ensure that these people can still
    use the page, they just don't have the bells and whistles of
    Javascript enhancements.

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
    Lasse Reichstein Nielsen, Mar 26, 2006
    #7
  8. Guest

    Lasse,

    Thanks for the reply.

    Lasse Reichstein Nielsen wrote:
    > writes:
    >
    > > I'm developing for an environment with client-side script support.

    >
    > That's the problem. In this group, the default assumption, unless
    > something else is said, is that the scripting is for web pages
    > for the internet. The internet as a whole is not an environment
    > where client-side script support can be assumed. The percentages
    > of people browsing without Javascript varies. TheCounter.com has
    > had numbers up to 9% late last year, but is currently at 3%.


    I wonder what those 3% are doing on the web? I have a feeling that
    anyone who wants to use my app with the dhtml widgets will have
    JavaScript running in thier browser. Otherwise...

    <noscript>
    <strong>Turn on JavaScript.</strong>
    </noscript>

    > > So that shouldn't be a problem. I get the feeling that you think
    > > using JavaScript is a bad idea.

    >
    > Javascript is a great idea for *enhancing* pages, but if the page
    > *depends* on Javascript, then there are people who cannot use it at
    > all.


    I understand this argument. Mission critcal pages like an ecommerce
    store front probably shouldn't have JavaScript dependence.

    Who cannot use JavaScript? Not to be an instigator but if this argument
    is taken to an only slightly larger level we could argue that we should
    not write <form>s with <button>, <select> etc tags because people
    without an html browser will not be able to use the form. By writing
    for the web we are making assumptions. As time goes by can't we make
    more demanding assumptions as new techonology adoption improves? At
    only 3%, I think we are at a point where we can assume JavaScript is on
    for users of many types of web pages.

    Better to make a rich GUI page depend on JavaScript or Flash? If the
    JavaScript world doesn't think the answer is JavaScript then Flash will
    take over. I think a rich GUI library is really needed for JavaScript.
    I know that I need one. Otherwise I'm going to start writing Flash/Flex
    apps or Java Swing desktop apps that talk to my web server with SOAP.

    Peter
    , Mar 26, 2006
    #8
  9. writes:

    > PointedEars,


    >> Factually wrong.

    >
    > Why is it factually wrong? I am very interested in justified criticisms
    > of this method.


    I think the page does a decent job of explaining what it does, but
    what it does is a somewhat roundabout way of doing what it means to do :)

    I see no need for the init function to begin with. If you want to
    create a "subclass", you want the constructor function to call the
    "superclass" constructor and you want the objects to inherit each
    other. Introducing an "init" function that you can inherit is missing
    the point that the constructor already is a function.

    His fiddling with using a no-argument call to the constructor to
    create a clone of the prototype object is just a hack. There are
    easier ways to create clones of objects.

    E.g.
    ----
    function Person(first,last){
    this.first = first;
    this.last = last;
    }
    Person.prototype.toString = function toString() {
    return this.first + " " + this.last;
    };

    function Employee(first, last, id) {
    this.superclass(this, first, last);
    this.id = id;
    }
    Employee.prototype = clone(Person.prototype);
    Employee.prototype.constructor = Employee;
    Employee.prototype.superclass = Person;
    Employee.prototype.toString = function toString() {
    return this.id + ":" + this.super.toString.call(this);
    };

    function Manager(first, last, id, department) {
    this.superclass(first, last, id);
    this.department = department;
    }
    Manager.prototype = clone(Employee.prototype);
    Manager.prototype.constructor = Manager;
    Manager.prototype.superclass = Employee;
    Manager.prototype.toString = function toString() {
    return this.super.toString.call(this) + " manages " + this.department;
    };

    function clone(prototype) {
    function dummy(){};
    dummy.prototype = prototype;
    var clone = new dummy();
    clone.super = prototype;
    return clone;
    }
    ----

    You could even make an "extend" function for doing most of this work:
    ---
    /**
    * Makes constructor extend superclass by inheriting
    * from superclass.prototype and extending its own
    * prototype with "superclass" referring to superclass
    * and "super" referring to "superclass.prototype".
    */
    function extend(constructor, superclass) {
    function dummy(){};
    dummy.prototype = superclass.prototype;
    var prototype = new dummy();
    prototype.constructor = constructor;
    prototype.superclass = superclass;
    prototype.super = superclass.prototype;
    constructor.prototype = prototype;
    return constructor;
    }

    function Person(first, last) {
    this.first = first;
    this.last = last;
    }
    Person.prototype.toString = function toString() {
    return this.first + " " + this.last;
    };
    function Employee(first, last, id) {
    this.superclass(first, last);
    this.id = id;
    }
    extend(Employee, Person);
    Employee.prototype.toString = function toString() {
    return this.id + ":" + this.super.toString.call(this);
    };
    ----


    I'm also not convinced that trying to program class-based in a
    prototype-based language is the best way to work. There are
    plenty of people trying to build class scaffoldings around
    Javascript, but learning to program prototype based is probably
    better in the long run.

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
    Lasse Reichstein Nielsen, Mar 26, 2006
    #9
  10. Guest

    Lasse,

    Thank you for your reply. Very interesting. I will study this in more
    detail.

    > I'm also not convinced that trying to program class-based in a prototype-based language is the best way to work.


    This sounds very reasonable. How is one to learn and develop intution
    about the best way to work in a prototype based language? I find the
    idea very foreign even though I've been playing with JavaScript for
    months. I'm sure this problem plagues many people used to Java, C++,
    Ruby, etc when they start learning JavaScript. This problem probably
    causes a lot of bad JavaScript being written.

    What would this example of people, employee and manager look like in a
    more prototype inheritance way?

    Thanks,
    Peter
    , Mar 26, 2006
    #10
  11. Roman Guest

    Lasse Reichstein Nielsen wrote:
    > writes:
    >
    >> I'm developing for an environment with client-side script support.

    >
    > That's the problem. In this group, the default assumption, unless
    > something else is said, is that the scripting is for web pages
    > for the internet. The internet as a whole is not an environment
    > where client-side script support can be assumed. The percentages
    > of people browsing without Javascript varies. TheCounter.com has
    > had numbers up to 9% late last year, but is currently at 3%.
    >
    >> So that shouldn't be a problem. I get the feeling that you think
    >> using JavaScript is a bad idea.

    >
    > Javascript is a great idea for *enhancing* pages, but if the page
    > *depends* on Javascript, then there are people who cannot use it at
    > all. Graceful degredation would ensure that these people can still
    > use the page, they just don't have the bells and whistles of
    > Javascript enhancements.
    >
    > /L


    The topic started as JavaScript GUI library idea, so it should be safe
    to assume that we have "some" JS support. The gracefull degradation
    would be nice, but is absolutely not on the top of the requirements for
    me. The web-app would gracefully notify the user w/o JavaScript about
    this requirement and render nothing. Users not willing or not able to
    enable JS would be simply left-out.

    Roman
    Roman, Mar 26, 2006
    #11
  12. Guest

    Lasse Reichstein Nielsen wrote:

    > You could even make an "extend" function for doing most of this work:
    > function extend(constructor, superclass) {
    > function dummy(){};
    > dummy.prototype = superclass.prototype;
    > var prototype = new dummy();
    > prototype.constructor = constructor;
    > prototype.superclass = superclass;
    > prototype.super = superclass.prototype;
    > constructor.prototype = prototype;
    > return constructor;
    > }


    I've been playing with this. This idea is really great! Nice an clean.
    (Why didn't I think of that?)

    Thanks again,
    Peter
    , Mar 26, 2006
    #12
  13. Randy Webb Guest

    said the following on 3/25/2006 9:55 PM:
    > Lasse,
    >
    > Thanks for the reply.
    >
    > Lasse Reichstein Nielsen wrote:
    >> writes:
    >>
    >>> I'm developing for an environment with client-side script support.

    >> That's the problem. In this group, the default assumption, unless
    >> something else is said, is that the scripting is for web pages
    >> for the internet. The internet as a whole is not an environment
    >> where client-side script support can be assumed. The percentages
    >> of people browsing without Javascript varies. TheCounter.com has
    >> had numbers up to 9% late last year, but is currently at 3%.

    >
    > I wonder what those 3% are doing on the web?


    With the advent of non-scriptable PDA's and Cell Phones I am not sure I
    would believe that 3%. Historically, it has been between 10-20% that are
    non-scriptable. But I do believe that the trend is towards scripting and
    not away from and if the 3 and 9 are correct then that backs up my belief.

    > I have a feeling that anyone who wants to use my app with the dhtml
    > widgets will have JavaScript running in thier browser. Otherwise...
    >
    > <noscript>
    > <strong>Turn on JavaScript.</strong>
    > </noscript>


    The only problem with that approach is that if scripting is enabled and
    for some reason there is a script error in the page, the user doesn't
    get the content delivered via JS and they won't see the noscript block.

    --
    Randy
    comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
    Randy Webb, Mar 26, 2006
    #13
  14. writes:

    > What would this example of people, employee and manager look like in a
    > more prototype inheritance way?


    I won't claim I'm an expert on prototype based programming, but here is
    my take on it ...

    First, there are no classes. Objects inherit from other objects and
    are then specialized. I.e., to make "a person similar to John, but
    with another name", you do:

    var paul = clone(john);
    paul.first = "Paul";
    paul.last = "McCartney";

    Javascript makes this proces easy, because they do both cloning and
    update in one operation using an initialization function (aka
    constructor function), so you would have:

    function PersonSimilarToJohn(first,last) {
    this.first = first;
    this.last = last;
    }
    PersonSimilarToJohn.prototype = john;

    Sometimes you start out with an *idea* of a person, more than a real
    person. You create an object that can serve as the prototype for
    actual objects without really being one itself - an abstract prototype.
    You do that by createing a real object with default values:

    var john = {first: "John", last: "Doe",
    toString: function toString(){return first + " " + last;}};

    or without them (usually directly on the existing prototype object
    of the initializer function):

    function Person /* aka PersonSimilarToPersonPrototype */() {
    this.first = first;
    this.last = last;
    }
    Person.prototype.toString = function toString(){return first + " " + last;};


    So far, Javascript is with us. Now, if you want to further specialize
    a person, you can either do it directly:

    function employ(person, newId) {
    person.id = newId;
    var oldToString = person.toString;
    person.toString = function() {
    return this.id + ":" + oldToString.call(this);
    }
    }

    After calling this, that person is employed. It's hard to fire him, since
    it's the same object that is modified.

    Another approach is to create a new object view of PersonAsEmployee:

    function employ(person, newId) {
    function Employee(person, newId) {
    this.person = person;
    this.id = newId;
    };
    Employee.prototype = person;
    var employee = new Employee(newId);
    employee.toString = function() {
    retrun this.id + ":" + this.person.toString();
    };
    employee.asPerson = function() {
    return this.person;
    }
    return employee;
    }

    Here your employee inherits from a real person. If that person changes
    his name, so does the employee. You can employ the same person several
    times at different companies.
    (A better modelling to begin with would perhaps be a person having a
    number of employments, so employee again becomes just a role of a
    person, not a special type of person).

    This is looking at a person as the primary entity, and being employed
    as a role.


    Likewise, you can promote to manager by extending the person or by
    making a manager view of the person.

    Since Javascript doesn't have multiple inheritance, you can't inherit
    from both a person and a manager prototype. That is why I add the
    emplyee and manager features manually instead of on an initializer
    prototype. I believe Self could do multiple inheritance.

    The general pattern for creating new objects is: Take an existing
    object, clone it, and adapt the clone to the new needs. I.e.,
    "I want something like that, only with the exceptions ... ".


    A somewhat less prototype base approach would be the one I suggested,
    where you keep a parallel hierarchy of prototype objects and
    initializers, so that an actual employee is created based on the
    prototype of a person extended to a prototype of an employee, and then
    initialized as both. This is clearly class based thinking (which
    appears to be much easier to grok for the average programmer :)


    Ob-link:
    <URL:http://en.wikipedia.org/wiki/Prototype-based_programming>

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
    Lasse Reichstein Nielsen, Mar 26, 2006
    #14
  15. Guest

    Lasse,

    Wow, thanks for writing such a detailed explanation. Better than what
    I've read before.

    Prototype-style programming looks like a really different mind set.
    Certainly not the way my mind has been trained to think. Perhaps it was
    a fluke of this person/employee/manager example but the code using
    simulated class-based inheritance seems less bulky to me.

    I think that me using simulated class-based inheritance in JavaScript
    would not be the end of the world because
    1) a lot of people know and think in class-based inheritance
    2) a lot of people use JavaScript infrequently and don't know prototype
    inheritance well
    3) I haven't yet run into a downside for simulating class-based
    inheritance in JavaScript
    4) JavaScript allows for a short, tidy way to simulate class-based
    inheritance (your extend function). Since it is such a short and tidy
    method using the prototype I'm surprised this is looked down upon at
    all. It *is* native JavaScript and only a few lines of code at that. It
    doesn't create a nightmare like using goto statements. It is just a
    different style of prototype manipulation. You can program in C++ or
    Java either in an OOP or procedural style. And some people are happy
    with one or the other. You can even program in C to simulate classes.

    Maybe one day the whole idea of the intended use of prototype style
    will click in my head and I will be trying to simulate that in Ruby.

    Lasse, thanks again for helping educate my brain.

    As a note, I emailed Kevin, the author of the
    class-based-inheritance-in-JavaScript tutorial and a friendly guy. He
    says that your extend function is very similar to what he uses now and
    he has had plans to update his tutorial to reflect this.

    Peter
    , Mar 26, 2006
    #15
  16. Guest

    I want to use simulated namespaces and so am defining my "classes" with
    function literals. I found that Safari could not quite use the extend
    function if the superclass constructor was defined as a function
    literal. Seems like there must be a Safari bug. Firefox had no trouble.
    I added a line to the extend function to explicitly set the
    constructor.

    Also Safari did not like the use of a property named "super" in the
    original example.

    -Peter

    function extend(subclass, superclass) {
    function Dummy(){};
    Dummy.prototype = superclass.prototype;
    subclass.prototype = new Dummy();
    subclass.prototype.constructor = subclass;
    subclass.prototype.superclass = superclass.prototype;
    // Safari needs some help if the superclass constructor
    // is defined with a function literal
    subclass.prototype.superclass.constructor = superclass;
    };

    Person = function(first, last) {
    this.first = first;
    this.last = last;
    };
    Person.prototype.toString = function toString() {
    return this.first + " " + this.last;
    };

    Employee = function(first, last, id) {
    this.superclass.constructor(first, last);
    this.id = id;
    };
    extend(Employee, Person);
    Employee.prototype.toString = function toString() {
    return this.id + ":" + this.superclass.toString.call(this);
    };

    var e = new Employee("ted", "henry", 18);
    document.write(e.toString());
    , Mar 26, 2006
    #16
  17. writes:

    > I want to use simulated namespaces and so am defining my "classes" with
    > function literals. I found that Safari could not quite use the extend
    > function if the superclass constructor was defined as a function
    > literal. Seems like there must be a Safari bug. Firefox had no trouble.


    There's always one more bug :)

    > I added a line to the extend function to explicitly set the
    > constructor.


    Shouldn't be necessary, but ... well. If it is, it is.


    > Employee = function(first, last, id) {
    > this.superclass.constructor(first, last);


    Here the method is called with "this" referring to this.superclass,
    i.e., the extended functions prototype. That means that the first
    and last properties are set on that, not on this object. If you create two
    emplyees, they will have the same name, the second of the two.
    You have to do:
    this.superclass.constructor.call(this, first, last);
    to avoid this. (This was why I preferred the "superclass" property on
    the object itself - you could call it without having to use "call")

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
    Lasse Reichstein Nielsen, Mar 27, 2006
    #17
  18. Guest

    Lasse Reichstein Nielsen wrote:

    > There's always one more bug :)


    I think there is another one and I think I know what is going wrong.
    When I make the example contain the third level of Manager I get
    infinite recursion on the superclass call in the Employee constructor.
    This is because when extend(Manager, Employee) is called it overwrites
    this.superclass with Employee for the object. So when Employee tries to
    call it's superclass it calls itself.

    I think this is why in Kevin's tutorial he didn't add the superclass to
    the instances but rather he added the superclass property to the Class
    constructor of each class up the hierarchy.

    Peter

    extend = function(subclass, superclass) {
    function dummy(){};
    dummy.prototype = superclass.prototype;
    subclass.prototype = new dummy();
    subclass.prototype.constructor = subclass;
    subclass.superclass = superclass.prototype;
    subclass.superclass.constructor = superclass;
    }

    Person = function(first, last) {
    this.first = first;
    this.last = last;
    }
    Person.prototype.toString = function toString() {
    return this.first + " " + this.last;
    };
    Employee = function(first, last, id) {
    Employee.superclass.constructor.call(this,first, last);
    this.id = id;
    }
    extend(Employee, Person);
    Employee.prototype.toString = function toString() {
    return this.id + ":" + Employee.superclass.toString.call(this);
    };

    Manager = function(dept, first, last, id) {
    Manager.superclass.constructor.call(this,first, last, id);
    this.dept = dept;
    }
    extend(Manager, Employee);
    Manager.prototype.toString = function toString() {
    return this.dept + ":" + Manager.superclass.toString.call(this);
    };

    var e = new Manager("DEPT", "ted", "henry", 26);
    document.write(e.toString());
    , Mar 27, 2006
    #18
  19. wrote:

    [snip]
    > I've been asking questions about library design over the last week and
    > would like to get feedback on my overall idea for a JavaScript GUI
    > library. I need a nice GUI library so there is a good chance I will
    > write this as I need new widgets.I haven't found anything like this
    > and I'm surprised/disapointed this doesn't already exist.

    [/snip]

    But what about:-

    <URL:http://www.bindows.net>
    <URL:http://dojotoolkit.org/> (In particular, Widgets)
    <URL:http://www.activewidgets.com/>

    Regards

    Julian
    Julian Turner, Mar 27, 2006
    #19
  20. mallen Guest

    Julian Turner wrote:
    > But what about:-
    >
    > <URL:http://www.bindows.net>
    > <URL:http://dojotoolkit.org/> (In particular, Widgets)
    > <URL:http://www.activewidgets.com/>


    or

    <URL:http://qooxdoo.oss.schlund.de/>

    Which is OSS (unlike activewidgets and bindows) and conatins a pretty
    full featured set of common ui widgets (unlike Dojo).
    mallen, Mar 27, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    10
    Views:
    1,234
    Big K
    Feb 2, 2005
  2. Dr Mephesto

    App idea, Any idea on implementation?

    Dr Mephesto, Feb 4, 2008, in forum: Python
    Replies:
    3
    Views:
    714
    Dennis Lee Bieber
    Feb 5, 2008
  3. Replies:
    0
    Views:
    632
  4. Victor \Zverok\ Shepelev

    Refactorings again: idea for library

    Victor \Zverok\ Shepelev, Sep 26, 2007, in forum: Ruby
    Replies:
    1
    Views:
    95
    Trans
    Sep 26, 2007
  5. Replies:
    0
    Views:
    84
Loading...

Share This Page