5 ms·
JavaScript: what is "this"?
- nailer 17y agoIt's this.
- nailer 17y agoI appreciate that HN isn't Reddit, and expect that comment to be treated appropriately, but somewhere I hope there's a Hacker who loves Faith No More and just smiled.
- tumult 17y agoIt's not entirely our fault, the language was designed to work like one thing (scheme-like), but look like another (c-like). The baseless assertion rears its head again. People keep repeating this, and it's not true. JavaScript is not Scheme. It's not any more Scheme-like than Java, C++, Python, Perl, or many other languages. Lua and Ruby are far more Scheme-like than JavaScript. I've commented before on people repeating this statement without ever examining it. I don't want to dredge up the arguments against it again ( http://news.ycombinator.com/item?id=1171202 http://news.ycombinator.com/item?id=1171202 ), mostly I just want to whine at it because it's so annoying. Why do you have to make JavaScript seem like something it's not? Are you trying to seem cooler by equating the language you work in to Scheme? What's wrong with JavaScript just being what it is?
- audionerd 17y agoI think the author is just citing how influential Scheme was to JavaScript's design. In "Coders at Work", page 141, Brendan Eich talks about wanting to build a scheme-like language for the browser. The c-like syntax was adopted because Netscape wanted it to look like Java.
- tumult 17y agoMaybe he wanted to. If that was his goal, I think he failed. Scheme: First-class functions, tail-call elimination, macros, hygienic macros, write and parse the AST directly. JavaScript: First-class functions. Scheme: Immutable arrays and lists, mutable strings. JavaScript: Mutable-only arrays, immutable-only strings. Yes, I have, and have read, Coders at Work. I don't see how it's relevant. JavaScript and Scheme share only one defining feature in common, first-class functions. It's an important feature, no doubt, but many other languages have it: C/Objective-C (with Apple's blocks extension), C++ (with Boost.Lambda), Perl, Python, Ruby, Lua, Io, OCaml, ML, Haskell, the list goes on. People compared Perl to Lisp once, briefly, when it was one of the few dynamic languages, but they don't anymore.
- chromatic 17y agoPeople compared Perl to Lisp once, briefly, when it was one of the few dynamic languages, but they don't anymore. They should; Perl 5 compares quite well and Perl 6 fares even better (of the nine fundamental features of a Lisp, lacking only homoiconicity). See the book Higher-Order Perl, for example. http://hop.perl.plover.com/ http://hop.perl.plover.com/
- dfox 17y agoYou have to compare JavaScript with Scheme of the time when JavaScript was designed. Both macros and immutable structures are pretty recent (1999 and 2006 IIRC) additions to Scheme, previously such facilities were either non-existent or implementation-specific. While Scheme's syntax superficially looks like it's data, specification does not imply that there should be accessible AST as list structure anywhere (in contrast to Common Lisp, which is specified in terms of list structures and algorithm to build them from text serialization) And by the way: You have left off the one most important defining feature of Scheme: first-class continuations. And JavaScript really does not have them (I would say that this is completely reasonable omission for JS's purpose)
- avibryant 17y agoOh, come on, you're cherry picking the features that suit your argument. If we include "garbage collected", that gets rid of C and C++. If we include "dynamically typed", that gets rid of OCaml, ML, Haskell. If we include "single namespace for functions and variables", that gets rid of Ruby, Io, and Perl. Now we're down to JavaScript, Python, and Scheme, which, yes, are all in basically the same family of languages. If you add the (admittedly subjective) feature "small language spec", that gets rid of Python, and we're left with JavaScript and Scheme as the only two mainstream languages with that particular feature set.
- olavk 17y agoJavaScript definitely isn't Scheme (just as it definitely isn't Java either), but it is correct that it was conceived as a somewhat Scheme-like language with an OO-model inspired by Self, but for marketing reasons it was given a superficially Java-like syntax (and name!). It is interesting to imagine what could have happened if Netscape had shipped with a Lisp. Probably a lot more people would hate Lisp today!
- xtho 17y agoThis point of view is also maintained by D Crockford[1] who is supposed to know JavaScript's background. [1] IIRC eg in this presentation: http://www.infoq.com/presentations/The-State-and-Future-of-JavaScript http://www.infoq.com/presentations/The-State-and-Future-of-J...
- devinj 17y agoEgh, some of those other languages are more Scheme-like than others. In particular, Javascript is certainly more scheme-like than Java, which lacks even first-class functions, for example. And, well, Python is basically just Lisp with different syntax (or so Norvig claims; I'm not sure I'd go that far: http://norvig.com/python-lisp.html http://norvig.com/python-lisp.html). So I can't really agree that it's not any more Scheme-like than anything else out there. I do agree it's not particularly Scheme-like.
- jimbokun 17y agoJavascript's scoping is also closer to Scheme's lexical scoping, I think. If you always use var for local variables, their scope will always be the immediately enclosing function. With Python, the scope of a variable is less clear. To me, the combination of first class functions, anonymous function syntax, and lexical scope are very high on the list of features that make a language "Scheme-like."
- devinj 17y agoHow are Python's scoping rules less clear? They are identical to Javascript's (and Scheme's), except that instead of defaulting to global scope, they default to local scope (which can be overridden with `global foo`). Also, it has one extra kind of scope, class scope. I would agree with you if you said Python's class scope is rather strange, of course.
- i_tumult 17y agome smart. me know scheme. me know javascript unlike scheme. me make noise. me smart. ME SMART!
- rriepe 17y agoI had a lot of trouble with this as a newbie to Javascript. Glad to see it posted, even if it's months and months late for me.
- icode 17y agoHonestly, I think this is all too complicated. In Javascript, when you look at a line like this: a=1 you have to guess in which scope it changes or creates the variable a. I prefer the way PHP is dealing with scope. You simply know that "a=1" is only affecting the current scope.
- IgorPartola 17y agoWhich is why PHP is so much less flexible than JS. Also try this: $a = 1; function qqq() { global $a; unset( $a ); } qqq(); var_dump( $a ); P.S.: In PHP 5.1.6 calling unset() actually increases memory usage...
- devinj 17y agoI find it hard to believe that the largest cause (or even a significant cause) in the difference of flexibility of two languages is whether or not you can declare variables to belong to a given scope, and to which scope they default to.
- IgorPartola 17y agoI was referring more to the "feel" of the language rather than the fact that this individual feature is the single reason for why JavaScript is more flexible.
- rimantas 17y agoglobal $a in PHP is just another way to write $a =& $GLOBALS['a']; I.e. you just create reference to a global variable. Unsetting reference just breaks the tie between variable name and content.
- IgorPartola 17y agoExactly, which means that unset( $a ) is not the same thing as unset( $GLOBALS['a'] ). It makes perfect sense, just not a kind of thing you might not expect at first.
- WilliamLP 17y agoIf anyone wonders why every JavaScript framework under the sun rolls its own object system, and they're all incompatible, and almost nobody uses native JavaScript alone anymore, this is one of the reasons.
- adolph 17y agoWould you expand on this? Most frameworks share some convenience functions that make working in js or DOM easier and put all of their functions within a particular namespace instead of spamming global. Whats the problem?
- erlanger 17y ago> rolls its own object system === "Provides convenience functions for working with prototype chains." That has nothing to do with what makes the this keyword special in JavaScript, beyond prototypes affecting this' properties.
- WilliamLP 17y ago> "Provides convenience functions for working with prototype chains." Yes, that's pretty much what an object system is, isn't it? It's some convenience behaviour, but it would be nice if the language had a built-in way of doing things that wasn't so inconvenient.
- erlanger 17y agoI wasn't disputing that, I'm saying it's irrelevant to the discussion (the commenter implied that prototype modification is related to how this is determined in a given function call).
- tolmasky 17y agoI think it's pretty relevant. For example, something that is absolutely trivial in other languages (making super calls), is incredibly difficult to implement generically in JS, partially because of the way this behaves. This is something every class system (and of course just using prototype chains alone) in JS seems to run into. We ran into it early with Objective-J, and then CoffeeScript had the same problem: http://news.ycombinator.com/item?id=1014524 http://news.ycombinator.com/item?id=1014524
- btipling 17y agoThis kind of a bind is available in dojo via dojo.hitch and in google closure via goog.bind (make sure to require goog.base) There's a $.hitch plugin in JQuery, it doesn't come with it by default.
- erlanger 17y agoI feel it's worth noting that JavaScript developers refer to "this" as the execution context.
- endlessvoid94 17y agohttp://justin.harmonize.fm/index.php/2009/09/an-introduction-to-javascripts-this/ http://justin.harmonize.fm/index.php/2009/09/an-introduction...
- sesqu 17y agoThe var statement declares a variable as local to the current scope and the entire current scope, not just from the var statement onward. These local variables shadow any existing variables from outer scopes. Err, I tested this on Chrome's Inspector console, and I don't see such behaviour. The article says name should be undefined at the time of the comparison in the below code, but it isn't (and I frankly can't see why anyone would want it to be). Is this a feature of my execution environment, or have I just completely misunderstood what the author means? (function(name){var cmp=name=="tim"; var name; return cmp})("tim") // returns true
- papercrane 17y agoSince the comparison happens before var is declared, it will always evaluate to 'true'. I believe the author was thinking about something like so: (function(name) { var cmp = function() { return name=="tim"; }; var name; return cmp();})("tim"); This still evaluates to true, but I believe it has to do with the rules of shadowing. If you change the declaration to 'var name="bob";' it will return false.
- creationix 17y agoGood catch, I'm looking into this one. I know I've seen this behavior before in some JS environment. I'm glad it's not the case for V8 and will shortly update the article.