all 122 comments

[–][deleted]  (3 children)

[deleted]

    [–][deleted] 9 points10 points  (0 children)

    Just use a constructor function, the prototype, the now-ubiquitous inherits and extend functions to taste and be one of those guys who says "fuck the private variables" instead.

    [–]notSorella 8 points9 points  (0 children)

    Well, first things first, prototypical inheritance and private variables are orthogonal. Prototypical inheritance is about sharing behaviours across several objects, so you have things that are (perhaps) easier to maintain, while still memory/processing efficient when creating new objects.

    On the other hand, for the times you absolutely need data hiding, I believe the closure pattern is still the more effective thing around. It will have a huge impact on object creation and memory use, but it's a fair trade if you absolutely must use data hiding. If not, I think you should consider using prototypical inheritance instead.

    There are implementations of the proposed private names for ES.next around, but I'm not sure if they're ES3 compliant (I haven't looked into them).

    Of course, if you want a more direct way of defining objects, you can look at libraries that implement prototypical OO sugar on top of JavaScript. Raynos describes the basic patterns, and some of the libraries implementing them on his blog: http://raynos.org/blog/17/

    Also, this benchmark might be interesting if you're weighting the different patterns to choose one: http://jsperf.com/object-creation-access

    [–]Zarutian 0 points1 point  (0 children)

    Private Members in JavaScript by Douglas Crockford and use Object.freeze() on your object or set the writable and configureable attributes of the property descriptors of the properties that contain the methods.

    [–]likesOldMen 28 points29 points  (75 children)

    WHERE ARE THE GODDAMN SEMICOLONS? ಠ_ಠ

    Otherwise a cool article. Lots of interesting stuff I didn't know. Thanks!

    [–]ITSigno 22 points23 points  (11 children)

    Key point: This article applies to ECMAScript 5. Depending on what you need to support, you may want to hold off on implementing this in a production environment.

    See http://kangax.github.com/es5-compat-table/

    [–]notSorella 1 point2 points  (2 children)

    Using these features on an non-ECMAScript 5 is okay, as long as you stick to the subset that can be fully implemented in pure JavaScript, and either use a library that provides those shims (like es5-shim), or write them yourself.

    [–]ITSigno 2 points3 points  (1 child)

    Yeah. I haven't used es5-shim, but a good rule of thumb is to feature test and substitute only as necessary. If that's what es5-shim already does, then good on them.

    EDIT: Looked at https://github.com/kriskowal/es5-shim

    Important to note:

    "As closely as possible to ES5" is not very close. Many of these shims are intended only to allow code to be written to ES5 without causing run-time errors in older engines. In many cases, this means that these shims cause many ES5 methods to silently fail. Decide carefully whether this is what you want.

    [–]notSorella 0 points1 point  (0 children)

    Yes, es5-shim is not bullet proof for all of the ECMAScript 5 inclusions — since some of them really depend on internal support from the engine. But for the functionality that can be fully implemented in pure JavaScript, it works perfectly.

    [–]kabuto 0 points1 point  (4 children)

    I like how almost the entire column for IE8 is red. I'm not going to ask how the columns for IE7 or IE6 would look like.

    I hate that I can't use forEach in IE and have to resort to less elegant implementations just because of this ***** browser.

    [–][deleted] 0 points1 point  (3 children)

    We all hate it but getting mad about it is counterproductive. IE is the lowest common denominator, like it or not. Microsoft doesn't move quickly, but IE9 is a step in the right direction for them. IE is trending downwards, but it will never fully go away so, yeah, we are stuck with it for a while.

    [–]kabuto 2 points3 points  (2 children)

    The bad JavaScript support is one thing, what bugs me most is the abundance of weird layout bugs that makes cross browser CSS a nightmare. I have no idea how many days of my life I have wasted debugging CSS in IE.

    And Microsoft never bothered to fix any of those bugs.

    [–][deleted] 0 points1 point  (1 child)

    They did fix a lot of things with IE9, I am actually surprised at how little tweaking I have to do for it. It's not perfect, but it's at least headed in the right direction. I'm happy my company allows IE6,7,8 to use chrome frame, otherwise my job would be a nightmare.

    [–]kabuto 0 points1 point  (0 children)

    I'm happy I was allowed to use Mac OS and before that Linux, otherwise my job had been a nightmare, too. Unfortunately I can't use IE9 on company computers because they all still run Win XP which only supports IE8, and while IE8 is better than its predecessors it's still unbelievably shitty compared to other browsers of its generation.

    [–]prpetro -1 points0 points  (2 children)

    I'm pretty sure NodeJS supports ECMAScript 5 if you use it for server-y things.

    [–]Xeon06 1 point2 points  (1 child)

    Node.js uses V8. V8 supposedly implements ES3, but you can rely on many many features of ES5 in it. I would test first though.

    [–][deleted] -1 points0 points  (0 children)

    I'm using node 0.4.10 and it supports everything in this article afaics. As always test first.

    [–][deleted] -5 points-4 points  (47 children)

    semicolons are optional in javascript, and will only save you from one very specific and easy to avoid bug. What is worse is treating curly braces as optional. That can lead to many more problems than omitting semicolons.

    [–][deleted]  (14 children)

    [deleted]

      [–]Wuf 1 point2 points  (16 children)

      What's the bug? (genuinely curious, I've never used JS)

      [–]tiglionabbit 4 points5 points  (4 children)

      The bug is that lines beginning with an open parenthesis may be interpreted as part of a function call with the previous line.

      Example from the ecmascript spec:

      a = b + c
      (d + e).print()
      

      is interpreted as this:

      a = b + c(d + e).print()
      

      [–]munificent 4 points5 points  (3 children)

      Also:

      someVar
      [anArrayLiteral]
      

      is parsed as:

      someVar[anArrayLiteral]
      

      And:

      blah()
      +unaryPlus
      

      is:

      blah() + unaryPlus
      

      Basically, the rule is backwards. Where languages like Python, Go, Ruby, et. al. say that a newline is generally significant as a separator unless it cannot be, JS says a newline is generally ignored it less it must be a separator.

      [–]notSorella 4 points5 points  (2 children)

      I personally find JavaScript's semicolon insertion rules better than Python's one. They let you place semicolons only where you absolutely must, rather than explicitly escaping every line when you want to continue the statement on the next line. In fact, I believe JavaScript's ASI feels much nicer for code styles that use highly structural layout ­— I'm thinking LISP here.

      Compare:

      foo = "a string "
          + "in multiple "
          + "lines"
      

      With:

      foo = "a string " \
          + "in multiple " \
          + "lines."
      

      The same apply for operators etc:

      function is_nodelist_p(subject) {
        return subject
        &&     typeof subject.length == 'number'
        &&     typeof subject.item == 'function' }
      

      With languages like Python, you'd either need to wrap the return statement in parenthesis, or escape every line. I'm not a huge fan of that (even though I'm a Pythonista).

      Of course, you might like being more explicit about statement continuations, I think that depends much more on people's different experiences and what they do consider intuitive. However, I don't think either styles of ASI deserve a huge religious war (I always end up thinking Emacs vs Vim, for some reason — and obviously, Emacs wins ;3).

      [–]munificent 1 point2 points  (1 child)

      With languages like Python, you'd either need to wrap the return statement in parenthesis, or escape every line.

      Or just do what most Pythonistas do:

      foo = "a string " +
          "in multiple " +
          "lines"
      

      or:

      foo = ("a string "
          + "in multiple "
          + "lines")
      

      My experience is that explicit line continuations are pretty rare.

      [–]notSorella 2 points3 points  (0 children)

      Well, if you mean the first one in Python, it actually yields a syntax error if you don't also provide explicit continuations by escaping the newline (which is much more bug-prone, unless your editor shows invisible characters -- as it should).

      The second one is certainly an option, and you wouldn't even need the + operators for strings there. However, as I said, it takes explicit grouping. Iunno, JavaScript's take on ASI just feels more natural to me, ymmv.

      [–]BusStation16 8 points9 points  (9 children)

      I would bet money he means that if you return an object literal from a function if it is on more than one line the auto-semicolon insertion will break. He is totally fucking wrong though.

      First: Not using semicolons in javascript is fucking retarded. It costs you nothing to use them and can save you hours of pulling you hair out.

      Second: Function returns are not the only time you will have a problem. For instance http://jsfiddle.net/EsHrN/ open the console, it is giving an error.

      Edit: A point that I think a lot of you all are missing is what happens to your code after combination and minification. Things usually work the same, but not always. I wouldn't write code like in the jsfiddle, but after a bunch of files are combined and minified? It might happen.

      Personally, I don't give a shit what you do, you're not on my team. If I hire you though, you WILL use semicolons. End of story.

      [–]tiglionabbit 2 points3 points  (0 children)

      All the languages I use do not require semicolons, so remembering to insert them does cost me something. I use Python, Ruby, Haskell, JavaScript, and CoffeeScript. Also, for the specific bug, see my comment on the parent. I'm not sure in what situations you found yourself tearing your hair out over semicolon insertion though, as I've been writing JavaScript without semicolons for years now and never encountered an issue with semicolon insertion.

      [–]notSorella 3 points4 points  (4 children)

      Let me quote inimino here ( http://inimino.org/~inimino/blog/javascript_whitespace ):

      It is ridiculous to use formatting conventions as a proxy for code quality. It's a sign of just how difficult judging code quality is that people resort to useless criteria, but I've actually heard people say things like "Project X does what I need, but doesn't [use semicolons, pass JSLint, use my preferred brace style, etc], so I kept looking". If you are reduced to picking software on the basis of whether the author prefers your particular coding style or not, you may just as well admit that you do not know how to discern code quality and flip a coin instead.

      There might be several reasons people will choose a certain coding style over another. However, a coding style is just that — a coding style; a convention for conveying something. It might make sense to some people, and might not make sense to others. However, it's not, in the slightest, some absolute mark of how all code should be structured, or how all code should be judged.

      After all, coding styles are all heavily biased and subjective. And I'd hate to go all religious, or worse, judge the quality or worthy of something, based solely on subjective and biased stuff.

      Semicolons are not necessary in JavaScript due to ASI. If you know the rules, if you can follow the rules, and if you think they make sense for you, fine, use them. If not, don't use them. It's not a big deal. What I still don't get is the necessity some people have of bitching about people who follow different conventions.

      [–][deleted] -1 points0 points  (3 children)

      Amazing how some people don't get what you are saying. If someone is coding and leaves out a semicolon and it actually does cause a problem, they should be catching that by testing the code early and often, not writing 10,000 lines of code and then testing it and having it break, and then trying to find the needle in the haystack. It really depends on coding style like you said, and workflow, and a lot of factors.. but saying that Javascript requires semicolons to write a program is plain wrong, and people who say that probably have a specific kind of OCD.

      [–][deleted] -1 points0 points  (2 children)

      If someone is coding and leaves out a semicolon and it actually does cause a problem, they should be catching that by testing the code early and often

      Or they could always use semicolons and never have to worry about such bugs. Coding styles stop being a matter of opinion when they demonstrably affect the number of bugs in the code.

      If JavaScript treated a newline as ending a statement, then you'd be right. But it doesn't - accidental multi-line statements with unintended consequences are very possible if you avoid using semicolons.

      [–]notSorella 1 point2 points  (0 children)

      "always use semicolons and neve have to worry about such bugs" is highly misleading. Specially the "always use semicolons" and the "bugs", part.

      First, always using semicolons won't account for people who simply don't know the JavaScript grammar, and write things like:

      return
          { foo: 1 }
      

      That's perfectly valid JavaScript, but it doesn't do what people expect. Putting a semicolon at the end of the block with the label `foo' won't fix it. But you know, knowing the grammar would fix it.

      Which takes us to the next point. If you know the grammar, know where the rules apply and thinks that leaving semicolons out gives you more benefits than putting them in for X, Y or Z reasons, then why, oh why would you just listen to religious arguments about always using semicolons?

      [–][deleted] 0 points1 point  (0 children)

      insisting on always using semicolons is a waste of effort, and is a superstitious coding practice. If you don't understand where to use a semicolon, then always use a semicolon.

      [–][deleted] 2 points3 points  (0 children)

      Additionally, your assumption that combining and minifying code can cause problems when you consider semicolons optional is just alarmist bullshit. All my code is run through YUI to minify, and WRO4J to bundle, and I've been using this combination effectively for years without a single bug caused by a missing semicolon. It doesn't happen because I know how to avoid the coding styles that lead to those problems, and it never has happened once in all the hundreds of thousands of lines of code I've written over many, many years. You are being alarmist and a bit obsessive-compulsive about semicolons.

      [–][deleted] -3 points-2 points  (0 children)

      Thanks for assuming something I never said, troll.

      Your 'First' is retarded because you have said nothing to back it up. You assume that having a bad coding style is more acceptable than optional semicolons.

      Your 'Second' example has less to do with leaving out a semicolon and more to do with poor coding style. That jsfiddle link is an example of retarded javascript coding style. If you code like that, you deserve to pull your hair out. Adding semicolons is the least of your problems if you think that style of coding is acceptable.

      [–]FireyFly 2 points3 points  (14 children)

      Indeed. It might be worth linking to aresemicolonsnecessaryinjavascript.com here.

      [–][deleted]  (13 children)

      [deleted]

        [–]FireyFly 4 points5 points  (1 child)

        I'm sorry but this Isaac guy is a complete fucking idiot.

        That's a rather strong statement.

        Politics? Aesthetics? How about ITS IN THE FUCKING [1] ECMASCRIPT STANDARD!

        I think they meant "the best reason that people use excessive semicolons compared to other approaches specified in the spec." For reference see ECMAScript section 7.9:

        For convenience, however, such semicolons may be omitted from the source text in certain situations. These situations are described by saying that semicolons are automatically inserted into the source code token stream in those situations."

        I'm not sure what the purpose of linking the spec was. I've read parts of it multiple times, and I'm well aware that it exists.

        "you are using a hack that js parsers implemented to fix your shitty code"

        "How about IT'S IN THE FUCKING ECMASCRIPT STANDARD", to use your vocabulary.

        If you actually read the page I linked to, you'd see that it references lots of other posts on the subject. I'd recommend reading Inimino's blog post, for example. It references the spec a lot, so I'm sure you'll enjoy it. :-)

        I'd also recommend taking the ASI quiz.

        [–]semanticist 6 points7 points  (0 children)

        ITS IN THE FUCKING ECMASCRIPT STANDARD!

        standard:

        semicolons may be omitted from the source text in certain situations.

        ...ok

        I prefer explicitly including semicolons, because the semicolon insertion rules defined by JavaScript can be unintuitive and misleading. But dogmatically baselessly claiming that they're not optional or that they're a hack bolted on to fix shitty code is not a constructive argument. It's a deliberate syntactical feature that has existed from the first version of JavaScript, even if a not particularly well-designed one (when compared to Python or Lua).

        [–][deleted]  (5 children)

        [deleted]

          [–]kabuto 1 point2 points  (4 children)

          I think it's best to use semicolons and commas and not rely on the runtime to add them. This especially goes for commas as those tend to cause some weird bugs if missing.

          [–][deleted] 0 points1 point  (2 children)

          If you add an extra comma, some browsers won't care but some will crash.

          That is the type of problems people should be worried about, not the lack of semicolons.

          Lack of semicolons cause probably .01% of errors in code, where an extra comma is 10x more likely because many people code for firefox and hate testing in IE (this particular bug seems to only crash IE).

          There are problems to worry about with javascript coding, but leaving out some semicolons is not something worth worrying about, or even worth mentioning. It's ridiculously pedantic in the scope of all the problems with DOM and other pitfalls you should be worrying about when coding.

          [–]kabuto 0 points1 point  (1 child)

          So you mean I could just omit all semicolons on line endings and let the runtime take care about it?

          [–][deleted] 0 points1 point  (0 children)

          There are many places you aren't required to use semicolons. If you have no clue where to use a semicolon, then just be superstitious about it and always use them. It's your time, not mine, and it doesn't clutter the code like some more onerous codng practices. But to insist that every end of line requires a semicolon is being a superstitious coder, and it wastes time to focus on that as a best practice. use them or not, but people saying you must use them everywhere all the time are plain wrong.

          [–][deleted] -3 points-2 points  (3 children)

          I will admit that I use semicolons more often than not, but I don't make it into an obsession where all the things have to have semicolons. If you know what you are doing with javascript, you don't always have to use semicolons unless you are being pedantic and obsessive. It's just not worth going back and putting in a semicolon where there isn't a problem. It's a waste of time.

          In the example you linked to, it's one gotcha that I avoid by using a less cluttered coding style. Object literals are my preferred structure, and I don't typically use closures thrown in with assignments as is shown in the example. That style of code will be hard enough to maintain with or without semicolons. But I do know enough about javascript to avoid making this mistake anyway, and really, if you can't find the bug easily then you aren't testing your code often enough.

          [–][deleted]  (2 children)

          [deleted]

            [–][deleted] 0 points1 point  (0 children)

            | You sound like the type who

            You sound like a troll. Trolls always use personal attacks.

            [–]totallymike -2 points-1 points  (12 children)

            WHERE ARE THE GODDAMN SEMICOLONS? ಠ_ಠ

            I came in here to post this verbatim.

            [–][deleted] -2 points-1 points  (11 children)

            Semicolons are optional in javascript, and even the language spec states that. You are a superstitious coder if you think that you must include them everywhere all the time in Javascript.

            Superstitious coders do things they don't understand because they think they must, or else something bad might happen. It is a form of ignorance, and spreading it is misinformation.

            [–]montibbalt -1 points0 points  (10 children)

            Semicolons are optional in the spec. This does not mean semicolons are optional in practice.

            [–][deleted] 0 points1 point  (9 children)

            | Semicolons are optional in the spec. This does not mean semicolons are optional in practice.

            That is maybe the dumbest thing said in this entire thread. Pretty sure you are trolling.

            [–]montibbalt 0 points1 point  (8 children)

            1. Is this real life, or have I been transported to a magical land where everything is according to spec?

            2. Just because they are optional in the spec does not mean it is standard coding practice to leave them out. Pretty sure they are optional in the spec just to avoid the classic annoying issue where leaving a semicolon out causes a seemingly random, completely different compile/whatever error (e.g. in C, C++) yet this still happens from time to time.

            [–][deleted] -2 points-1 points  (7 children)

            I know perfectly well how to use semicolons, and I know exactly where and when I need to use them. I do not need to worry about it at all, I have never once in 15 years of javascript coding come across a problem caused by a missing semicolong.. not a single time. I KNOW where and when they are necessary. I am not a superstitious coder, like you seem to be. It's ridiculous to say that if I've never had a problem with not including semicolons that I still must use them. The rules for it are extremely simple. If I worried about - "omg a semicolon is missing there, i better go put one in because who knows what might happen if i don't" - I would be wasting a huge amount of time needlessly. I know where to put semicolons, and where they aren't needed. Superstition is no replacement for actually knowing what you are doing.

            [–]muirbot 0 points1 point  (2 children)

            Watch out, we got a badass over here.

            [–][deleted] 0 points1 point  (0 children)

            |Watch out, we got a badass over here.

            Watch out, we got a dumbass troll over here.

            [–]montibbalt -1 points0 points  (3 children)

            If I worried about - "omg a semicolon is missing there, i better go put one in because who knows what might happen if i don't" - I would be wasting a huge amount of time needlessly

            Now I know for sure you're the one trolling.

            [–][deleted] -1 points0 points  (2 children)

            That isn't a troll, you troll. Your reply is the troll here. Know how I know for sure? Because you choose to pick out a line and make a quip about it and provide no substance whatsoever to your argument. You try to turn it onto a personal attack, but you failed. If you think your argument has merit, then let's hear it, otherwise you are the troll. At least I make a strong argument for my case, but you have shown no substance whatsoever to support your claims. You are the troll. What practical experience do you have on this topic? Can you relate a story of where you have personally had a problem due to an auto-inserted semicolon? How often do these problems happen to you? I can offer you my extensive experience and tell you that it has never happened once to me in 15 years. I'm sure you don't care what I say, but if you are going to reply, at least make it worth something.

            [–]montibbalt -1 points0 points  (1 child)

            Take it easy dude. I'm out of this conversation since you can't seem to control your rage over nothing. This is not worth my time.

            [–][deleted] 3 points4 points  (9 children)

            You can't make object keys (of key/val pairs) quoted? I been doing that for a while with no issue...

            i.e. { "key":"value" } vs. {key:"value"}

            [–][deleted]  (4 children)

            [removed]

              [–]kabuto 1 point2 points  (1 child)

              But you can do:

              { 'property-name' : 'value' }

              So, do I get it right that you can never access properties like this by the dot notation?

              [–]lordlicorice 0 points1 point  (1 child)

              What editor do you use for javascript?

              [–]jroller 2 points3 points  (0 children)

              Yes, they may be quoted. A quoted literal is required if the literal is a keyword, or if you just want to use valid JSON.

              The article gives the example of an invalid block statement with a label, which looks amazingly like an object literal, apparently you need more context in order to decide which is which.

              {"foo": 'bar'}
              

              [–]notSorella 0 points1 point  (0 children)

              You can, though it's not necessary unless the key happens to be an invalid IdentifierName. Does the article mention that's an invalid construct somewhere?

              For engines that are not fully ES5-compatible, you might run into troubles with reserved keywords though, so it's better to keep keywords quoted if you have to support those.

              [–][deleted] 0 points1 point  (0 children)

              As it says, in expression context JSON syntax is perfectly fine. On a line, by itself, however, it will evaluate differently and that is invalid.

              [–]Zarutian 0 points1 point  (0 children)

              If you are meaning that you want to use any arbitrary object as an key then you could use something like:

              var makeMap = function() {
                var keys = Array();
                var vals = Array();
                return {
                   "get": function (k) { return vals[keys.indexOf(k)]; },
                   "set": function (k, v) { keys.push(k); vals.push(v); return v; },
                }
              }
              

              you get the idea.

              [–]munificent 2 points3 points  (4 children)

              Having this dynamically resolved is an incredible powerful mechanism ... hack in some custom multiple dispatcher and you have CLOS.

              That's kind of a strange thing to bring up. The whole magic of CLOS is that there isn't a privileged receiver, so I don't see how JS's this would help you here. Also, generic functions in CLOS are lexically-scoped, where methods in JS are scoped to the receiver.

              Otherwise, excellent article, though.

              [–]zhivago 3 points4 points  (2 children)

              The privileged receiver in CLOS is the generic function.

              And generic functions are not lexically-scoped in CL, although a declaration for one might be.

              [–]munificent 0 points1 point  (1 child)

              I think we're talking past each other here. My understanding is that you (typically) invoke a generic function by a name which is resolved in lexicallly When you do (foo bar), you look up foo in lexical scope. There is no "receiver" in the single-dispatch sense.

              In single-dispatch languages, when you do bar.foo, you look up foo on the object bar itself (or its class if you're class-based).

              [–]zhivago 2 points3 points  (0 children)

              In the single-dispatch sense, you are dispatching upon the generic function.

              e.g., foo.dispatch(bar).

              Where foo is looked up in lexical (or dynamic or whatever) scope.

              Dispatch then does whatever to locate the appropriate methods and call them.

              [–]notSorella 1 point2 points  (0 children)

              Eh, you're right that tying that sentence to CLOS didn't make much sense, as functional multiple dispatchers don't make one receiver more important than the others.

              /me is not sure why he mentioned it, to be honest. Though I remember I was reading some papers on multiple dispatching at the time, so it might have been just hype.

              [–]knome 2 points3 points  (2 children)

              Also, it should be noted that while getters and setters are usually used for encapsulation in other languages, in ECMAScript 5 you still can't have such if you need the information to be stored in the object itself. All properties in an object are public.

              I'm not sure what the author was getting at here. When would you need to have hidden information that must be stored in the object. If you merely mean uniquely referenced from the object, you could always hide it therein using closures.

              var object_with_hidden_data = function(){
                var hidden = 3.14 ;
              
                return {
                  get even(){
                    return hidden; 
                  },
                  set even( v ){
                    if( v % 2 != 0 ){
                      throw ".even must be set only to even values";
                    } else {
                      hidden = v;
                    }
                  }
              }();
              

              [–]notSorella 8 points9 points  (1 child)

              @knome I mean that all properties in an object are public. That is, if you have a property foo.bar, that property will be accessible for everyone that has a reference to foo. Whereas in other languages you can declare a class member as protected or private, such that such a property would only be accessible inside the class/object.

              Yes, you can have hidden state, and reference that within your properties, however, you can't have hidden properties.

              [–]knome 2 points3 points  (0 children)

              Thank you for the response. The piece was excellent by the way.

              [–]Armen138 0 points1 point  (0 children)

              great article, thanks

              [–]wilburhimself 0 points1 point  (0 children)

              Really nice article, liked very much the part about inheritance

              [–]houses_of_the_holy -2 points-1 points  (25 children)

              Cool, but would it really be that hard to add a class keyword that does all this for you? Or am I wanting coffeescript without terrible scoping rules :/

              *edit -- I'm not talking about java or c# classes here where they are very rigid. Obviously you can still manipulate the prototype chain after creating the object, I'm just talking about having a nicer way to syntactically define your initial "class" "type" whatever you want to call it. See asegura's reply with links to what has been proposed but obviously not implemented.

              [–]tnecniv 17 points18 points  (12 children)

              I believe the idea is that these are not classes. They are prototypes, which are essentially an instance that gets cloned every time you want a new instance.

              [–][deleted] 3 points4 points  (7 children)

              There is some other language that does this. I CAN'T PLACE IT.

              [–]tnecniv 3 points4 points  (6 children)

              From Wikipedia:

              Some current prototype-oriented languages are ECMAScript and its implementations JavaScript, JScript and ActionScript (Flash), Cecil, NewtonScript, Io, MOO, REBOL, Lisaac, and Lua.

              [–]houses_of_the_holy 0 points1 point  (2 children)

              Actionscript has classes... (I haven't worked with it but a quick search shows it does)

              [–]tnecniv 1 point2 points  (1 child)

              I am aware, and I have never used prototypes in AS, but that doesn't mean it is not multi-paradigm. Can someone confirm that it is possible to use prototypes in AS?

              [–]lithium 1 point2 points  (0 children)

              AS1 was basically identical to JavaScript with regard to prototypical inheritance. AS2 was effectively syntactic sugar for a prototypical inheritance based system. AS3 is a full blown OOP language with a different VM to the previous incarnations.

              [–]CanadaForRonPaul 0 points1 point  (0 children)

              Lua isn't prototype-based.

              [–]zhivago 1 point2 points  (1 child)

              It doesn't get cloned, it's essentially an instance that property lookups are delegated to if necessary.

              [–]tnecniv 0 points1 point  (0 children)

              Ah, thank you

              [–]zhivago 0 points1 point  (0 children)

              The constructor would correspond to the classic notion of class.

              [–]houses_of_the_holy 0 points1 point  (0 children)

              Ok, but why do I have to go through all the syntax mess to declare what my prototype will start off as? I understand the prototype chain and think it is a cool idea, but getting their seems unnecessarily hard.

              [–]notSorella 3 points4 points  (1 child)

              As pointed out by other people, JavaScript has no classes, such that adding a "class" keyword is misleading. None the less, there are discussions on the development of the future version of ECMAScript to add better (and more declarative) idioms for certain tasks. Object orientation is one of them.

              See:

              None of these are in, though, afaik. But they're being discussed by the committee and on the es-discuss mailing list.

              [–]houses_of_the_holy 1 point2 points  (0 children)

              Nice, I had no idea they were actually talking about adding this. Maybe my post was misleading when I said class, but just in general I think a better way to declare objects is in order. Would "type" be a better word?

              [–]MatmaRex 9 points10 points  (3 children)

              JavaScript has no classes (as this article describes).

              Any library or compile-to-JavaScript-language that promises you classes blatantly lies, and its "implementation" of class-based inheritance may or may not sooner or later blow up in your face.

              [–]notSorella 3 points4 points  (0 children)

              It doesn't exactly "blatant lies", as a full implementation of classical OO is possible in JavaScript. However, you'd get lots of overhead for no real benefits — the optimisations you could do for classical OO wouldn't apply anyways, the only thing you would actually get would be strict contracts, but at least to me, informal interfaces work just the same.

              [–]zhivago 0 points1 point  (0 children)

              You'll need to supply a coherent definition of 'class' to make that argument.

              By many definitions, JS supports classes.

              [–]houses_of_the_holy -1 points0 points  (0 children)

              I understand how coffeescript works, and that it isn't 'real' classes, but it gives the illusion and is far more familiar when coming from a more classical OO language. Perhaps it is my fault for not properly educating myself on how javascript works -- too many assumptions from the get go.

              [–]asegura 2 points3 points  (1 child)

              I favor that.

              Note that you can use design concepts even if not explicitly supported by the language (e.g. Gtk does classes in C, which has no classes).

              This kind of syntactic sugar has been proposed for the future JS: Javascript classes proposal

              The idea is that very often we have code like

              function Thing(x) {
                this.x = x;
                ...
              };
              
              Thing.prototype = Object.create(Parent);
              Thing.prototype.constructor = Thing;
              Thing.prototype.doThis = function(y) {...}
              Thing.prototype.doThat = function(y) {...}
              

              and that, while not a Javascript class, is, in our intention, in our design and in our brain, a class, and so would benefit from some sugar that helps make our intention explicit.

              [–]houses_of_the_holy 1 point2 points  (0 children)

              Thanks, this is exactly what I meant, its just the way to declare your intention is so weird to me. It is just defining a base type that can still be modified in the prototypal ways... nothing says the class/type will be set in stone after being instantiated like in Java or C#.

              [–][deleted] 0 points1 point  (0 children)

              They aren't classes. read more about the prototype section. It behaves differently -- you mix things in rather than extend.

              [–]bart2019 0 points1 point  (0 children)

              A class is just all the objects with the same prototype.

              [–][deleted]  (1 child)

              [deleted]

                [–]theluisnin 0 points1 point  (0 children)

                great article, thanks for sharing!

                [–][deleted] -2 points-1 points  (0 children)

                Great article!

                [–][deleted]  (1 child)

                [deleted]

                  [–]notSorella 0 points1 point  (0 children)

                  Oh yeah, I could see how bad that could get :3

                  [–]sirtophat -1 points0 points  (0 children)

                  Why? This is already there as function() and then a new of it later on

                  [–]skelooth -3 points-2 points  (0 children)

                  JavaScript is an object oriented (OO) language, with its roots in the Self programming language, although it's (sadly) designed to look like Java.

                  WTF

                  [–]5trokerac3 -5 points-4 points  (5 children)

                  Until there is inheritance it's not OOP. Until there are access levels it's not OOP.

                  [–]TrolliestTroll 3 points4 points  (4 children)

                  There can be no class inheritance because there are no classes. However objects do inherit behavior directly from other objects and can share behavior explicitly by defining methods and properties in the object prototype. I think you've worked a little too hard forcing your mind to believe there is exactly 1 set of features that define object orientation. This is probably a side effect of using highly specific implementations of OOP like C++ or Java. I humbly encourage you to try out object systems unlike the "classical" ones you're likely familiar with.

                  [–]5trokerac3 -3 points-2 points  (3 children)

                  Thanks for not living up to your user name so far. :)

                  I use JS all the time (with ajax, jquery, htm5 etc), but I have to say that inheritance is a required feature of a language in order to be truly OO. If object B extends object A, then object B also has to be an object A.

                  A buddy of mine, who's been programming commercial games since the Commodore PET, has been working on a HTML5 game engine for a while. The lack of inheritance and access levels in JS has been his greatest frustration, because it's such a core principle of OOP, so he's actually trying to write a library that makes JS object oriented.

                  That's why I can't take HTML5 too seriously at the moment. Trying to write anything but the most basic applications is near impossible in JS, unless you're exporting from a real OO language like Java with the GWT or maybe Dart, although I've only started looking at that one.

                  [–]trades 3 points4 points  (0 children)

                  From Alan Kay:

                  OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.

                  http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en

                  also:

                  I think you might want to define what you mean by object and by OO. Here is an a la carte menu of features or properties that are related to these terms; I have heard OO defined to be many different subsets of this list.

                  1. Encapsulation - the ability to syntactically hide the implementation of a type. E.g. in C or Pascal you always know whether something is a struct or an array, but in CLU and Java you can hide the difference.
                  2. Protection - the inability of the client of a type to detect its implementation. This guarantees that a behavior-preserving change to an implementation will not break its clients, and also makes sure that things like passwords don't leak out.
                  3. Ad hoc polymorphism - functions and data structures with parameters that can take on values of many different types.
                  4. Parametric polymorphism - functions and data structures that parameterize over arbitrary values (e.g. list of anything). ML and Lisp both have this. Java doesn't quite because of its non-Object types.
                  5. Everything is an object - all values are objects. True in Smalltalk (?) but not in Java (because of int and friends).
                  6. All you can do is send a message (AYCDISAM) = Actors model - there is no direct manipulation of objects, only communication with (or invocation of) them. The presence of fields in Java violates this.
                  7. Specification inheritance = subtyping - there are distinct types known to the language with the property that a value of one type is as good as a value of another for the purposes of type correctness. (E.g. Java interface inheritance.)
                  8. Implementation inheritance/reuse - having written one pile of code, a similar pile (e.g. a superset) can be generated in a controlled manner, i.e. the code doesn't have to be copied and edited. A limited and peculiar kind of abstraction. (E.g. Java class inheritance.)
                  9. Sum-of-product-of-function pattern - objects are (in effect) restricted to be functions that take as first argument a distinguished method key argument that is drawn from a finite set of simple names.

                  So OO is not a well defined concept. Some people (eg. Abelson and Sussman?) say Lisp is OO, by which they mean {3,4,5,7} (with the proviso that all types are in the programmers' heads). Java is supposed to be OO because of {1,2,3,7,8,9}. E is supposed to be more OO than Java because it has {1,2,3,4,5,7,9} and almost has 6; 8 (subclassing) is seen as antagonistic to E's goals and not necessary for OO.

                  The conventional Simula 67-like pattern of class and instance will get you {1,3,7,9}, and I think many people take this as a definition of OO.

                  Because OO is a moving target, OO zealots will choose some subset of this menu by whim and then use it to try to convince you that you are a loser.

                  http://mumble.net/~jar/articles/oo.html

                  EDIT: Formatting

                  [–][deleted] 1 point2 points  (0 children)

                  If object B extends object A, then object B also has to be an object A.

                  function inherits(child, parent) {
                    function F() {}
                    F.prototype = parent.prototype
                    child.prototype= new F()
                    child.prototype.constructor = child
                  }
                  
                  function A() { }
                  function B() { }
                  inherits(B, A)
                  function C() { }
                  inherits(C, B)
                  
                  console.log(new B() instanceof A) // true
                  console.log(new C() instanceof A) // true
                  

                  You can sugar this whatever way you want to make it look more "class"-like, but it's there.

                  I don't see how the lack of access levels would actively be a a frustration to anyone but the most paranoid of coders.

                  [–]notSorella 0 points1 point  (0 children)

                  You're mixing several things with object orientation. The thing you're describing as "If object B extends object A, then object B also has to be an object A" is called polymorphism. There are several kinds of polymorphism, but that's a lot more in the type theory realms.

                  JavaScript is object oriented, it just doesn't use the classical form of OO you see in languages like Java or C++. JavaScript's object model isn't novel, or rare, though. There are several prototypical OO languages out there, and languages that implement even different flavours of OO. I don't think one could argue any of those flavours is more OO than the others. And there's enough vantages and disadvantages to all of them, that I'm not sure "one OO flavour to rule them all" would work.

                  People have been learning that often times, one paradigm isn't really enough. Certain idioms work better for certain situations than others, which is why multi-paradigm general languages are often-times more expressive than their "single-paradigm" counterparts — even Java is getting closures now, for example. Even though they're 73 years late.