www.webdeveloper.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 16

Thread: Js oo?

  1. #1
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787

    Js oo?

    I ran into someone who insisted that javascript was not an object oriented language. the guy is finishing up his phd in information science, so he's not foolish or ignorant. i can attest he is very knowledgeable about computer science...

    i explained that everything was an object in javascript, how could it not be oo? I never got a clear explanation of what he meant because had to leave before we could finish our conversation. he mentioned something about not having encapsulation...



    i think he is wrong, but can anyone shed some light on what he was possibly trying to get at?


    does something disqualify javascript from being an object oriented language?


    is this a common sentiment among classical programmers?

  2. #2
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    JavaScript is object oriented, but not class based. JavaScript "classes" are function objects with a property called "prototype" that is used to set default values for a new object.

    JavaScript does not support encapsulation, whereby you declare properties and methods private, public or protected in order to enforce a standard interface to the object. Encapsulation is a hallmark of classical inheritance object oriented programming, not of object oriented programming itself.
    Code:
    Object Oriented Programming
      - Class based objects (class definition and object are separate)
      - Prototype based objects (Object prototype used to construct new objects)
    Class-Based vs. Prototype-Based Languages
    Last edited by toicontien; 12-11-2008 at 03:03 PM. Reason: Clarifying "javascript classes"

  3. #3
    Join Date
    Aug 2007
    Posts
    3,767
    Sounds to me like malapropism too. I doubt he seriously thought that JavaScript wasn't OO, but simply misused the word.

  4. #4
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by toicontien View Post
    JavaScript does not support encapsulation, whereby you declare properties and methods private, public or protected in order to enforce a standard interface to the object.
    interesting. let me ask you this: is it that javascript cannot create these kinds of properties, or rather that it lacks the formal ways of declaring them?

    it seems to me that you can do this in a constructor.
    Code:
    function  Hello(s){ //Hello constructor
        var what= String(s) || ""; // private variable
     
        this.say =  function(){ //public method
                alert( "Hello " + what );
            }
    
    }
    crockford outlines public and private, and what he terms "privileged" in this article

    i bet that we can use getters and setters to create protected properties.
    can anyone think up a js1.5 way to accomplish protecteds?

  5. #5
    Join Date
    Mar 2005
    Location
    Sydney, Australia
    Posts
    7,974
    It is actually private variables that are the ones that can't be done in JavaScript. The one you have labelled as private is actually protected. Deriving another object based on this one would still have access to that variable.
    Last edited by felgall; 12-11-2008 at 03:47 PM.

  6. #6
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    @rnd me: You have created a function closure in your example. While philosophically the same as a privileged or private member, literally it is not. The "what" variable does not exist in the Hello.prototype object, so "what" is not a property of objects created using the Hello constructor function.

    But it does serve the same purpose: Prevents code outside of the object from setting or accessing the value of "what" and enforcing an interface (using the say() public method). This is as close as JavaScript gets to encapsulation.

    It's also good to note that the say() public method must be created each time a Hello object is created, whereas properties and methods in the Hello.prototype object are created when the page first loads. When a Hello object is created, the properties and methods in the Hello.prototype object are linked to the instantiated object, using the __proto__ property of all objects, which links to the prototype object from which the current object's methods and properties are derived.
    Last edited by toicontien; 12-11-2008 at 04:12 PM.

  7. #7
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by felgall View Post
    It is actually private variables that are the ones that can't be done in JavaScript. The one you have labelled as private is actually protected. Deriving another object based on this one would still have access to that variable.
    that sounds great, but can you please show an example of this?

    i've been working on the code below, but i cannot reach what or bornOn from g.

    Code:
    function  Hello(s){ //Hello constructor
        var what= String(s) || ""; // private variable
       var bornOn = new Date;
         this.say =  function(){ //public method
                alert( "Hello " + what );
            }
    }//end Hello
    
    
    function  Greetings(name){
         this.hello = new Hello(name);
    }
    var g=new Greetings("fred");
    g.hello. ???

    so how would one get to what or bornOn from g?

    I've tried a lot of things, even the eval trick, but i am stumped...



    @toicontien -
    good post. i was hoping it was not merely a battle of words.. it seems most computer science disagreements are about semantics, not capabilities.
    Last edited by rnd me; 12-11-2008 at 04:35 PM.

  8. #8
    Join Date
    Mar 2005
    Location
    Sydney, Australia
    Posts
    7,974
    Start with

    Greetings = new Hello();

    and then add the extra functionality that you want Greetings to have that it hasn't inherited from Hello.

  9. #9
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by felgall View Post
    Start with

    Greetings = new Hello();

    and then add the extra functionality that you want Greetings to have that it hasn't inherited from Hello.
    I trust you know what you are talking about, but I cannot figure it out.

    what's your secret felgall?

    try as i might, i cannot gets subs to reach a top constructor's var.

    it seems that unless i define a method inside the constructor function itself, bornOn is unreachable.

    i am going nuts over here,
    please give a tiny example, please?



    Code:
    function  Hello(s){ //Hello constructor
        var what= String(s) || ""; // private variable
       var bornOn = new Date;
         this.say =  function(){ //public method
                alert( "Hello " + what );
            }
    }//end Hello
    
    Hello.prototype.getAge=function(){ return bornOn.toString(); }
    
    g= new Hello("fred");
    g.getAge() //exception
    EDIT. ps i am using "Private restricts the access to the class itself. Only methods that are part of the same class can access private members." as a definition for private...

    thanks for your help so far!

  10. #10
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    @felgall: To set up basic inheritance in JavaScript (including some extra things), shouldn't it be:
    Code:
    function Greeting() {
      // Call parent class's say() method
      this.base.say.apply(this);
      
      // Call overridden say() method
      this.say();
    }
    
    // "Inherit" from Hello
    Greeting.prototype = new Hello();
    
    Greeting.prototype.base = Hello.prototype;
    
    Greeting.prototype.additionalMethod = function() {};
    
    // Override Hello.say
    Greeting.prototype.say = function() {};

  11. #11
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    @rnd me: My advice to anyone using OOP in JavaScript is to treat JavaScript what it is: a prototype based language where every object member is public. Creating closures to emulate private or protected variables just obfuscates your code, makes it harder to maintain, and simply tries to make JavaScript into something it isn't: an inheritance, class based language that forces an interface.

    To answer your question:
    Code:
    function  Hello(s){ //Hello constructor
        var what= String(s) || ""; // private variable
       var bornOn = new Date;
         this.say =  function(){ //public method
                alert( "Hello " + what );
         }
         this.getDate = function() {
            return bornOn;
         };
    }
    
    Hello.prototype.getAge=function(){
      return this.getDate().toString();
    }
    Just my opinion.

  12. #12
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by toicontien View Post
    @rnd me: My advice to anyone using OOP in JavaScript is to treat JavaScript what it is: a prototype based language where every object member is public. Creating closures to emulate private or protected variables just obfuscates your code, makes it harder to maintain, and simply tries to make JavaScript into something it isn't: an inheritance, class based language that forces an interface.

    To answer your question: ...
    Just my opinion.
    1st i want to say thanks for good posts, a lot more interesting discussing than fixing 10 year old snowflake scripts...

    what you show is the "privileged pattern" crockford writes about.
    I mean, wouldn't that.getDate().toString() do the same thing?
    the only reason bornOn is accessible outside the constructor is because it was closed by the getDate function.
    if you did not have the inner getDate function (made public), you cannot construct a tack-on that can reach bornOn.

    that to me sounds like a private variable, and it walks like one too...

    functions including constructors have scope.
    this scope is private to the right of a var, and global on a new line/semi.
    You can poke out aliases, but you cannot reach an original, local var by itself.
    right? i know firefox2 and 3.0 have that secret 2nd argument to eval, but other than that, i don't think so.

    to comment on your post @ felgall, you might try crockford's object function.
    it's a lot less to type out when setting up simple inheritances.

    check it out:
    Code:
    var object = (function() {
         function F() {}
         return function(o) {
             F.prototype = o;
             return new F();
         };
    })();
    
    //  usage example
    var a = {a:1,b:2,c:3}
    var b = object(a)
    b.a=5; //b={a:5,b:2,c:3}; a={a:1,b:2,c:3}
    a.b=99 //b={a:5,b:99,c:3}; a={a:1,b:99,c:3}
    changes in a are reflected in both, but changes to b happen only to b...

    this accomplishes close to what you were doing, but nary a "prototype" or "apply" in sight...
    Last edited by rnd me; 12-12-2008 at 12:53 AM.

  13. #13
    Join Date
    Mar 2005
    Location
    Sydney, Australia
    Posts
    7,974
    That's what I get for hinting at an approach without going into a full description.

    If you're interested in getting a book on OOjs then "Object Oriented JavaScript" by Stoyan Stefanov published by Packt Publishing which came out in July this year contains lots of useful info.
    Last edited by felgall; 12-12-2008 at 01:15 AM.

  14. #14
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    Quote Originally Posted by felgall View Post
    If you're interested in getting a book on OOjs ...
    thanks, i'll check it out.

    there's about 101 ways to do various objecty things in javascript, and there are good sides to all of them. no, it will never be exactly like one language or the other.

    It's a testament to javascript that it can come close to so many in so many ways in so few keywords.

    perhaps as a language, it's the second best at everything...


    what would be nice is seeing several, well written example how to wire up 4 or 5 common pseduo classes, inheritance schemes, etc.
    different design patterns if you will.
    not only how, but i think more important is why.

    knowing when a mock classical or swiss inheritance is going to solve the problem best for the situation.
    or that other, and which, jobs screams out for a prototype solution.

    we all have several of these tricks up our sleeves, but i think that having something written about when and where would be a great resource.
    it would be nice if several would coalesce into standard practices over time.








    perhaps the book
    Last edited by rnd me; 12-12-2008 at 02:06 AM.

  15. #15
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    The article below did a lot of demystifying of JavaScript for me. It's well worth your time to read and digest.

    https://developer.mozilla.org/en/Cor...ased_Languages

    I'm not against trying to implement things like multiple inheritance, class interfaces, and private and protected variables, I'm just against making code harder to read than is necessary. I've found that -- and most JavaScript libraries out there suffer from this -- a lot of code is written in near gibberish to accomplish something a classical inheritance based language just does on its own. I take the view of; if I want a Ferrari, I'll buy a ferrari. I'm not going to spend the time and effort bolting a Ferrari engine to my Chevy Cavalier. The Cavalier gets me to where I'm going just as well as the Ferrari does, and driving and maintaining a Cavalier is easier than driving and maintaining a Ferravalier.

    I created a function that allows JavaScript "classes" to behave like traditional inheritance classes, but a test project I was doing just seemed sluggish. Performance wise, the method below is quickest:
    Code:
    function ParentClass() {
      
    }
    ParentClass.prototype = {
      
      property1 : "",
      
      method1 : function() {}
      
    };
    
    function ChildClass() {
      // Constructor code
    }
    ChildClass.prototype = new ParentClass();
    ChildClass.prototype.base = ParentClass;
    
    ChildClass.prototype.method2 = function() {};
    This seems pretty much in line with Douglas Crockford's article about Prototypal Inheritance. This is the direction I've steadily been heading. I'm still not fully convinced private and privileged methods and variables are worth the overhead of creating them upon each instantiation of a new object (i.e. some opinions to the contrary are encouraged ).

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles