views:

38069

answers:

106

What "Hidden Features" of JavaScript do you think every programmer should know?

After having seen the excellent quality of the answers to the following questions I thought it was time to ask it for JavaScript.

Even though JavaScript is arguably the most important Client Side language right now (just ask Google) it's surprising how little most web developers appreciate how powerful it really is.

+151  A: 

Functions are first class citizens in JavaScript:

var passFunAndApply = function (fn,x,y,z) { return fn(x,y,z); };

var sum = function(x,y,z) {
  return x+y+z;
};

alert( passFunAndApply(sum,3,4,5) ); // 12

Functional programming techniques can be used to write elegant javascript.

Particularly, functions can be passed as parameters, e.g. Array.filter() accepts a callback:

[1, 2, -1].filter(function(element, index, array) { return element > 0 });
// -> [1,2]

You can also declare a "private" function that only exists within the scope of a specific function:

function PrintName() {
    var privateFunction = function() { return "Steve"; };
    return privateFunction();
}
Gulzar
There are three ways to make functions in javascript: function sum(x, y, z){ return (x+y+z);}and var sum = new Function("x", "y", "z", "return (x+y+z);");are the other ways.
Marius
The concept of functions-as-data definitely wins big points in my book.
Jason Bunting
I just updated the sample to show how to use a "private" function that exists only within the scope of a specific function.
Chris Pietschmann
`new Function()` is as evil as `eval`. Do Not Use.
Nicolás
I don't think function-as-data === function-as-first-class-citizens... Yes you can do some string manipulation + eval/new Function() magic. But that's wayyyy different from how Scala/Lisp has it.
chakrit
`new Function()` may indeed be evil. But we have no way of knowing since you haven't told us why.
Kyralessa
not sure this is a hidden feature... more like a core feature.
Claudiu
+102  A: 

Private Methods

An object can have private methods.

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    // A private method only visible from within this constructor
    function calcFullName() {
       return firstName + " " + lastName;    
    }

    // A public method available to everyone
    this.sayHello = function () {
        alert(calcFullName());
    }
}

//Usage:
var person1 = new Person("Bob", "Loblaw");
person1.sayHello();

// This fails since the method is not visible from this scope
alert(person1.calcFullName());
Allain Lalonde
Pedantry: JavaScript doesn't have classes. It is possible to have functions that are accessible to members of an object but otherwise inaccessible.
Shog9
Fair enough changed.
Allain Lalonde
That's not really a private function - it's more a function variable in a local scope.
Keith
True but by all operational definitions I can think of that's a method. It's a block of code with a name that has access to instance state and can only be seen by that instance. What's your definition of a private method?
Allain Lalonde
One that exists in the definition of the class rather than the instance. In the example above the function variable calcFullName could be reassigned to something else, and the logic is being worked out again each time.
Keith
I agree with Keith... While knowing the technicals qualify as an hidden feature (or more like "a not well known feature") of JavaScript, its use for "private methods" is more a hack than anything else.
paercebal
I don't think you can call that a method since a new function is created in each object instance. A method is in the prototype and can be changed once to change all objects. Add the fact that with this technique, your objects take much more memory.
Vincent Robert
@Vince, It's an instance method. @Kieth, implementation details are different for every lang. What should be considered is whether it provides the necessary level of information hiding to be called private.
Zach
@Zach, exactly! It's easy, after spending years working with class-based OO languages, to forget that they are merely one implementation of OO concepts. Of course, the various libraries that attempt to cram quasi-class-based OO into JS don't help either...
Shog9
Why the hell would you want private methods? Real object-oriented languages don't have them (see Smalltalk).
omouse
Just wondering, does person1 have a Law Blog? ;-)
travis
No just sounds like blah blah blah. I use that name all the time when teaching.
Allain Lalonde
If you insist on calling it private methods expect confusion when the real and proper classes get implemented in the next standard. Although I guess we are used to explaining things like that in JAVA-Script. :P
Kit Sunde
+1 for the arrested development reference
Domenic
@travis – I haven't watched the show, but I asked the same question when I encountered that character's name. And I checked; there *is* a [blog](http://thebobloblawlawblog.blogspot.com/)!
Kenny Evitt
any language with closures and first-class functions can do this. i think it's missing the point to call it a "private method". more accurate would be "you can kind of simulate private methods by declaring a function inside a constructor". where the abstraction breaks down: if you declare a function in `Person`'s prototype, it won't be able to access the `calcFullName` "private method". Calling it a "private method" just confuses people and makes it seem like JavaScript has class-based OOP.
Claudiu
+53  A: 

with.

It's rarely used, and frankly, rarely useful... But, in limited circumstances, it does have its uses.

For instance: object literals are quite handy for quickly setting up properties on a new object. But what if you need to change half of the properties on an existing object?

var user = 
{
   fname: 'Rocket', 
   mname: 'Aloysus',
   lname: 'Squirrel', 
   city: 'Fresno', 
   state: 'California'
};

// ...

with (user)
{
   mname = 'J';
   city = 'Frostbite Falls';
   state = 'Minnesota';
}

Alan Storm points out that this can be somewhat dangerous: if the object used as context doesn't have one of the properties being assigned to, it will be resolved in the outer scope, possibly creating or overwriting a global variable. This is especially dangerous if you're used to writing code to work with objects where properties with default or empty values are left undefined:

var user = 
{
   fname: "John",
// mname definition skipped - no middle name
   lname: "Doe"
};

with (user)
{
   mname = "Q"; // creates / modifies global variable "mname"
}

Therefore, it is probably a good idea to avoid the use of the with statement for such assignment.

See also: Are there legitimate uses for JavaScript’s “with” statement?

Shog9
Conventional wisdom the with statment is to be avoided. If the user object didn't have one of the properties you mentioned, the variable outside the with block's pseudo-scope would be modified. That way lies bugs. More info at http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/
Alan Storm
If you misspell the variable name, you've introduced a bug. Period. Personally, i never use with for stuff like this, but it is somewhat of a "hidden feature" so...
Shog9
Shog, the objections aren't about misspelled variables, they're about looking at a block of code, and being able to say with certainty what any particular line in that block does. Because Javascript objects are so dynamic, you can't say with certainly what properties/members it has at any moment.
Alan Storm
Good point. I'll revise my response to note this.
Shog9
Amen - if I saw the "with" statement in any JS I found, I would eliminate it and question the developer that wrote it to make sure he knew why it was not a Good Thing to use it..."hidden feature?" More like "abhorrent feature."
Jason Bunting
consider a more complex chain a.b.c.d "with (a.b.c) {d.foo = bar;} is powerful and not inherently error prone. The key is to curtail the root one level up. And misspelling a variable name? You're introducing a bug if you do that *wherever* you do it, regardless of "with".
annakata
if you need to change half? function augment (a, b) { for(i in b) { a[i] = b[i] } return a}
Breton
Douglas Crockford recently said "with" is one of the worst parts of JavaScript in a .NET Rocks! podcast.
Chris
@Chris: Crockford has maintained that for some time, and he has good reasons for saying that. However, it does provide something not provided by any other language construct: a way of directly augmenting name resolution scope (functions provide this indirectly). Use with caution.
Shog9
Most of the time you can get by using loops and something like jQuery.extend to gets the same effect.
chakrit
I agree that with() is evil. One more thing that may convince you is that you cannot use jslint or a minifier (like YUI compressor or Google Closure Compiler) with it. Any scope in which with() appears won't be optimised, and can't be checked for variable scope (because you don't know the scope of a variable until runtime).
thomasrutter
yes please don't use with. it breaks lexical scoping, makes code confusing, etc.
Claudiu
+102  A: 

You can access object properties with [] instead of .

This allows you look up a property matching a variable.

obj = {a:"test"};
var propname = "a";
var b = obj[propname];  // "test"

You can also use this to get/set object properties whose name is not a legal identifier.

obj["class"] = "test";  // class is a reserved word; obj.class would be illegal.
obj["two words"] = "test2"; // using dot operator not possible with the space.

Some people don't know this and end up using eval() like this, which is a really bad idea:

var propname = "a";
var a = eval("obj." + propname);

This is harder to read, harder to find errors in (can't use jslint), slower to execute, and can lead to XSS exploits.

Patrick
eval is evil, though rarely necessary
Doug D
I never use eval and remember when I discovered this. It made me very happy.
Improfane
In summary, object properties can be accessed through both dot and subscript notation
Russ Cam
It's interesting to note that dot-referencing is actually syntax sugar for the bracketref. `foo.bar`, according to the spec anyway, behaves just like `foo["bar"]`. also note that everything is a string property. even when you do array access, `array[4]`, the 4 is converted to a string (again, at least according to ECMAScript v3 spec)
Claudiu
+58  A: 

"Extension methods in JavaScript" via the prototype property.

Array.prototype.contains = function(value) {  
    for (var i = 0; i < this.length; i++) {  
        if (this[i] == value) return true;  
    }  
    return false;  
}

This will add a contains method to all Array objects. You can call this method using this syntax

var stringArray = ["foo", "bar", "foobar"];
stringArray.contains("foobar");
spoon16
This is generally considered a bad idea, because other code (not yours) may make assumptions about the Array object.
Chris Noe
It's also generally considered a bad idea to make assumptions about the Array object. :(
eyelidlessness
Uhmmmm.. javascript 1.6 array extras? indexOf? ringing any bells?
Breton
@Breton: It's not something specific to the Array class, it's just an example. I use this to extend the new Date().toString(); method, allowing to use a mask string. *Any* object can be extended, and all it's instances get the new method.
voyager
+87  A: 
CMS
Not if it's null, if it's considered false. a = 0 || 42; will give you 42. This is comparable with Python's or, not C#'s ?? operator. If you want the C# behavior, do a = (b === null) ? c : b;
Armin Ronacher
sweet! works with firebug.
Rajat
Like the term "falsy" :)
Jonas
It also works in Visual Studio as well, if you develop on ASP.NET :)
chakrit
I wish there was proper || for undefined only. I was bitten by this today for 0, since I wanted to create emulation of overloaded method, so that the last argument was optional and a default value would be used instead.
egaga
That default value trick is pretty awesome. +1
Jasconius
+3  A: 

It's surprising how many people don't realize that it's object oriented as well.

Vaibhav
I think this is in large part due to Javascript's OO-ness being entirely prototype based rather than the class based OO of the more popular languages. Also, JS is sparse on OO syntactic niceties, which can be a real turn off, especially if you're learning.
Wedge
Weird. How else would they interpret document.writeln or document.getElementsbyTagName?
Allain Lalonde
@allain you'd be suprised
Justin Johnson
Because I believe most developers use Javascript on browsers and don't care much about how OO it is. they are using basic stuff to do something on browsers if they are highly using server-side codes.
Braveyard
+100  A: 

JavaScript does not have block scope (but it has closure so let's call it even?).

var x = 1;
{
   var x = 2;
}
alert(x); // outputs 2
eed3si9n
That is a good one. It is a really important difference from most C like languages.
Martin Clarke
You can always do "var tmp = function() { /* block scope */ }();". The syntax is ugly, but it works.
Joeri Sebrechts
Or you can use "let" if it's Firefox only: http://stackoverflow.com/questions/61088/hidden-features-of-javascript#155730
eed3si9n
or just: (function() { var x = 2; })(); alert(typeof x); //undefined
Pim Jager
+26  A: 

How about closures in JavaScript (similar to anonymous methods in C# v2.0+). You can create a function that creates a function or "expression".

Example of closures:

//Takes a function that filters numbers and calls the function on 
//it to build up a list of numbers that satisfy the function.
function filter(filterFunction, numbers)
{
  var filteredNumbers = [];

  for (var index = 0; index < numbers.length; index++)
  {
    if (filterFunction(numbers[index]) == true)
    {
      filteredNumbers.push(numbers[index]);
    }
  }
  return filteredNumbers;
}

//Creates a function (closure) that will remember the value "lowerBound" 
//that gets passed in and keep a copy of it.
function buildGreaterThanFunction(lowerBound)
{
  return function (numberToCheck) {
    return (numberToCheck > lowerBound) ? true : false;
  };
}

var numbers = [1, 15, 20, 4, 11, 9, 77, 102, 6];

var greaterThan7 = buildGreaterThanFunction(7);
var greaterThan15 = buildGreaterThanFunction(15);

numbers = filter(greaterThan7, numbers);
alert('Greater Than 7: ' + numbers);

numbers = filter(greaterThan15, numbers);
alert('Greater Than 15: ' + numbers);
Tyler
i'm unsure, but can return (numberToCheck > lowerBound) ? true : false; simply become return (numberToCheck > lowerBound);just trying to increase my understanding...
davidsleeps
Yes, they're equivalent.
Tyler
I'd say anonymous functions in C# are equivalent of closures, not the other way around :)
vava
Closures and anonymous functions are separate, distinct concepts. That functions can be created without being named is having anonymous functions. That a variable in the 'creating' scope is linked with the created function is a closure. In short, a closure is more like a hidden global variable.
slebetman
That's true. Only when anonymous methods make use of a variable from the creating scope is it similar to a closure. I've updated the english on the answer. It still leaves something to be desired, but I'm at a lost for the correct english.
Tyler
I don't think this is the best or easiest to understand example of what a closure is. Just saying. The point of a closure is that even when a bunch of variables appear to 'go out of scope' they can still remain available to a function that was originally defined within that scope. In the above example, that means the lowerBound variable is still accessible by that inner, anonymous function even when the outer function, buildGreaterThanFunction, terminates.
thomasrutter
+25  A: 

You can also extend (inherit) classes and override properties/methods using the prototype chain spoon16 alluded to.

In the following example we create a class Pet and define some properties. We also override the .toString() method inherited from Object.

After this we create a Dog class which extends Pet and overrides the .toString() method again changing it's behavior (polymorphism). In addition we add some other properties to the child class.

After this we check the inheritance chain to show off that Dog is still of type Dog, of type Pet, and of type Object.

// Defines a Pet class constructor 
function Pet(name) 
{
    this.getName = function() { return name; };
    this.setName = function(newName) { name = newName; };
}

// Adds the Pet.toString() function for all Pet objects
Pet.prototype.toString = function() 
{
    return 'This pets name is: ' + this.getName();
};
// end of class Pet

// Define Dog class constructor (Dog : Pet) 
function Dog(name, breed) 
{
    // think Dog : base(name) 
    Pet.call(this, name);
    this.getBreed = function() { return breed; };
}

// this makes Dog.prototype inherit from Pet.prototype
Dog.prototype = new Pet();

// Currently Pet.prototype.constructor
// points to Pet. We want our Dog instances'
// constructor to point to Dog.
Dog.prototype.constructor = Dog;

// Now we override Pet.prototype.toString
Dog.prototype.toString = function() 
{
    return 'This dogs name is: ' + this.getName() + 
        ', and its breed is: ' + this.getBreed();
};
// end of class Dog

var parrotty = new Pet('Parrotty the Parrot');
var dog = new Dog('Buddy', 'Great Dane');
// test the new toString()
alert(parrotty);
alert(dog);

// Testing instanceof (similar to the `is` operator)
alert('Is dog instance of Dog? ' + (dog instanceof Dog)); //true
alert('Is dog instance of Pet? ' + (dog instanceof Pet)); //true
alert('Is dog instance of Object? ' + (dog instanceof Object)); //true

Both answers to this question were codes modified from a great MSDN article by Ray Djajadinata.

Tyler
+68  A: 

Functions are objects and therefore can have properties.

fn = function(x) {
   // ...
}

fn.foo = 1;

fn.next = function(y) {
  //
}
VolkerK
This is a very useful tip. For example, you can set default values as a property of the function. For example: myfunc.delay=100; Then users can change the default value and all function calls will use the new default value. For example: myfunc.delay = 200; myfunc();
BarelyFitz
Useful... and dangerous!
palswim
+162  A: 

I could quote most of Douglas Crockford's excellent book JavaScript: The Good Parts.

But I'll take just one for you, always use === and !== instead of == and !=

alert('' == '0'); //false
alert(0 == ''); // true
alert(0 =='0'); // true

== is not transitive. If you use === it would give false for all of these statements as expected.

Martin Clarke
I think I'll be picking that up. Thanks.
Allain Lalonde
Most people consider this one of the worst parts of the language when they first see it (3 equals!?). I think knowing about it is important though because it forces you to commit to memory that JavaScript is dynamically typed.
Allain Lalonde
Yes I agree - Crockford talks about in the "worst part" appendix. It is a shame they couldn't have just made "==" behave as expected.
Martin Clarke
It's a shame that so many people think Crockford is all-knowing. Granted, the guy is right on the mark with most of his criticisms, but I stop short of giving his stuff a blanket endorsement like so many devs do...
Jason Bunting
I might have misunderstood; but is their something in particular that you think he's off the mark on?
Martin Clarke
I second Jason's warning. The book in itself is very interesting, and it does give a lot of good advice, but DC is *far* too convinced that his way of doing things is the only correct way, everything else is "defective". If you'd like some examples, look at his responses on the JSLint Yahoo Group.
Zilk
thirded for all the reasons above, and especially for his commentary on "this"
annakata
Could someone explain to me why 0 == '' is true in javascript? What exactly does a nontransitive equality comparison mean?
Davy8
Nontransitive: '' == 0, and 0 == '0', but '' != '0'. If it was transitive, '' would equal '0'.0 == '' because type conversion is automatic, and some JS architect thought that '' should convert to 0.
Paul Marshall
Use === instead of == is good advice if you are confused by dynamic typing and just want it to be "really" equals. Those of us who understand dynamic typing may continue to use == for situations where we know we want to cast, as in 0 == '' or 0 == '0'.
thomasrutter
Well == and === are not about dynamic typing. == does type coersion, which is a different beast. If you know, that you want to cast to string/number/etc, then you shold do that explicitly.
Rene Saarsoo
The best use for == is when testing for undefined, because undefined == null, but undefined !== null. I've rarely seen anything where I want to differentiate between undefined and null.
Paul Marshall
@zlik: I completely agree. He is brilliant in some ways, but don't be afraid of re-writing his code. In particular, his PHP JSON-creation code is limited in how much it can assemble.
staticsan
I think the scariest part of `==` is `'\n\t\r ' == 0` => `true`... :D
Shrikant Sharat
I can see, that a lot of people still misunderstands JavaScript :)
chakrit
Crockford isn't perfect, but he revolutionized JS and made it into a usable language for the rest of us. He almost always backs his opinions with solid justifications. If I disagree with him 2% of the time, I don't think that's a big deal. When you do disagree, it's easy to customize JSLint's rule set with comments.
Neil Whitaker
+6  A: 

Javascript has static variables inside functions:

function someFunction(){
  var Static = arguments.callee;
  Static.someStaticVariable = (Static.someStaticVariable || 0) + 1;
  alert(Static.someStaticVariable);
}
someFunction() //Alerts 1
someFunction() //Alerts 2
someFunction() //Alerts 3

It also has static variables inside Objects:

function Obj(){
  this.Static = arguments.callee;
}
a = new Obj();
a.Static.name = "a";
b = new Obj();
alert(b.Static.name); //Alerts b
Marius
Nice! I had to take a triple take on this until I realized that you're defining a property on the function itself.I had to run alert(someFunction.someStaticVariable); for it to sink in.
Allain Lalonde
I think you're misrepresenting the ability of functions to have properties in general. What you say is technically true, but as a side effect to the functions being first order objects in the language.
levik
Agreed, this is a little misleading. "arguments.callee" is simply a reference to the function that was called. In your second example, a.Static === b.Static === Obj
Josh
+3  A: 

"undefined" is undefined. So you can do this:

if (var.field === undefined) ...
JW
"undefined" is not a reserved word, so this could potentially fail if you have a variable with that name.
levik
if you have a variable with that name, you've failed already
jsight
jsight, i'd like to voteup comments :P
Andrea Ambu
You can even change the value of the global `undefined`.
Ates Goral
A: 

As Marius already pointed, you can have public static variables in functions.

I usually use them to create functions that are executed only once, or to cache some complex calculation results.

Here's the example of my old "singleton" approach:

var singleton = function(){ 

  if (typeof arguments.callee.__instance__ == 'undefined') { 

    arguments.callee.__instance__ = new function(){

      //this creates a random private variable.
      //this could be a complicated calculation or DOM traversing that takes long
      //or anything that needs to be "cached"
      var rnd = Math.random();

      //just a "public" function showing the private variable value
      this.smth = function(){ alert('it is an object with a rand num=' + rnd); };

   };

  }

  return arguments.callee.__instance__;

};


var a = new singleton;
var b = new singleton;

a.smth(); 
b.smth();

As you may see, in both cases the constructor is run only once.

For example, I used this approach back in 2004 when I had to create a modal dialog box with a gray background that covered the whole page (something like Lightbox). Internet Explorer 5.5 and 6 have the highest stacking context for <select> or <iframe> elements due to their "windowed" nature; so if the page contained select elements, the only way to cover them was to create an iframe and position it "on top" of the page. So the whole script was quite complex and a little bit slow (it used filter: expressions to set opacity for the covering iframe). The "shim" script had only one ".show()" method, which created the shim only once and cached it in the static variable :)

Vitaly Sharovatov
+8  A: 

The way JavaScript works with Date() just excites me!

function isLeapYear(year) {
    return (new Date(year, 1, 29, 0, 0).getMonth() != 2);
}

This is really "hidden feature".

Edit: Removed "?" condition as suggested in comments for politcorrecteness. Was: ... new Date(year, 1, 29, 0, 0).getMonth() != 2 ? true : false ... Please look at comments for details.

Thevs
It's also overly complicated. I can't understand how anybody can write `cond ? true : false` (or vice-versa) and not notice how idiotic that is.
Konrad Rudolph
Just for clarity, the line should bereturn !(new Date(year, 1, 29, 0, 0).getMonth() == 2);Or, really, it should bereturn new Date(year, 1, 29, 0, 0).getMonth() != 2;
Jesse Millikan
In fact this notation isn't so idiotic as it may look, when 'undefined' results may be involved in further data.I took this example from a really working system, and changing this to "Politically Correct" form brakes the system totally :)
Thevs
@Thevs: I don't get how changing the form in this case would break anything. Both the old code and the new code seem to return real booleans (true/false) instead of merely returning objects which may or may not be truthy.
jsight
You are right. My mistake. It was "? 1 : 0" in my original code, and then return value had been added to 28 to determine a day count in February. Changing it to return boolean vlaue broke my code.In case of "? false: true" both code fragments are equivalent.
Thevs
Also, the secret return values of the "set..." methods:var d = new Date((new Date()).setHours(0, 0, 0, 0));
palswim
+3  A: 

All functions are actually instances of the built-in Function type, which has a constructor that takes a string containing the function definition, so you can actually define functions at run-time by e.g., concatenating strings:

//e.g., createAddFunction("a","b") returns function(a,b) { return a+b; }
function createAddFunction(paramName1, paramName2)
 { return new Function( paramName1, paramName2
                       ,"return "+ paramName1 +" + "+ paramName2 +";");
 }

Also, for user-defined functions, Function.toString() returns the function definition as a literal string.

Mark Cidade
This usually isn't necessary, though. In your example, you could just say: return function(paramName1, paramName2) { return paramName1 + paramName2; }
JW
It was just a contrived example. It's still a nice little-known feature. You can create macros with this, though, like unwinding a loop.
Mark Cidade
+289  A: 

You don't need to define any parameters for a function. You can just use the function's arguments array.

function sum() 
{ var retval = 0;
  for (var i=0; i < arguments.length; ++i) 
   { retval += arguments[i];
   }
  return retval;
}

sum(1,2,3) //returns 6
Mark Cidade
WHOA! Really?! I honestly had no idea.This site really needs a "favorite answers" feature. I'd add this one for sure.
Joshua Carmody
Worth noting though that although arguments acts like an array, it's not an actual javascript Array -- it's just an object. So you can't do join(), pop(), push(), slice() and so forth. (You can convert it to a real array if you want: "var argArray = Array.prototype.slice.call(arguments);" )
JacobM
It's also worth noting that accessing the Arguments object is relatively expensive -- the best examples are in Safari, Firefox, and Chrome nightlies where merely referencing the `arguments` object makes calling a function much slower -- eg. if(false) arguments; will hurt perf.
olliej
In the same vein, arguments has a "callee" property which is the current function itself. This allows to do recursion with anonymous functions, cool!
Vincent Robert
At least have the function signature include an argument named "varargs" or something to let readers know that your function has arity.
a paid nerd
This is cool, but is there a good reason you'd want to do this? Why not just pass in an array?
Nathan
@Nathan "f(x,y,z)" looks better than "f([x,y,z])".
Mark Cidade
@Nathan This `arguments` allows you bend and twist any existing functions to your will without even knowning the arguments. Try google for `Memoize Javascript` you'll get the idea of how this can be used.
chakrit
+16  A: 

All objects in Javascript are implemented as hashtables, so their properties can be accessed through the indexer and vice-versa. Also, you can enumerate all the properties using the for/in operator:

var x = {a: 0};
x["a"]; //returns 0

x["b"] = 1;
x.b; //returns 1

for (p in x) document.write(p+";"); //writes "a;b;"
Mark Cidade
Also, property names are strings, and if the string has a character that prevents it from being used through the dot notation, it can be accessed through the index notation. For example, an object property x['funky prop'] could not be accessed as x.funky prop; x['funky.prop'] cannot be accessed as x.funky.prop;
BarelyFitz
Just do not forget to check the property names with "object.hasOwnProperty(propertyName)" before using them from the for-in loop or else you'll experience some unwanted stuff ;)
BYK
@BYK: could you elaborate?
Beska
@Beska: I think the elaboration would be thus: for (p in x) if (x.hasOwnProperty(p)) document.write(p+";"); This gets around issues where adding new properties to x's prototype would cause _in_ to enumerate over them also, which may not be the desired behaviour.
brownstone
+117  A: 

You can use the in operator to check if a key exists in an object:

var x = 1;
var y = 3;
var list = {0:0, 1:0, 2:0};
x in list; //true
y in list; //false
1 in list; //true
y in {3:0, 4:0, 5:0}; //true

If you find the object literals too ugly you can combine it with the paramaterless function tip:

function list()
 { var x = {};
   for(var i=0; i < arguments.length; ++i) x[arguments[i]] = 0;
   return x
 }

 5 in list(1,2,3,4,5) //true
Mark Cidade
Not so clever, that checks if a key is present, not if a value is. x in list; only works because x[1] != null, not because the value 1 is there.
Armin Ronacher
I haven't used the technique ina while so I forgot that I actually used object literals before. Thanks for the correction.
Mark Cidade
Also, be careful: the in operator also tests the prototype chain!If someone has put a property called '5' on the Object.prototype, the second example would return true even if you called '5 in list(1, 2, 3, 4)'... You'd better use the hasOwnProperty method: list(1, 2, 3, 4).hasOwnProperty(5) will return false, even if Object.prototype has a property '5'.
Martijn
For the very most general solution, one that can test whether an Object has its own property, even if it is named "hasOwnProperty", you have to go all the way out to:Object.prototype.hasOwnProperty.call(object, name);
Kris Kowal
The best use for this (along with hasOwnProperty) is in a 3-state check... `queue[item] = false;` will makes `(item in queue) === true` but still retains `(queue[item] === false)` ... comes in handy in some situation (and looked wayyy cleaner that using hasOwnProperty)
chakrit
@Kris, not unless someone overwrites Object.prototype.hasOwnProperty ;)
Nick
+8  A: 

JavaScript uses a simple object literal:

var x = { intValue: 5, strValue: "foo" };

This constructs a full-fledged object.

JavaScript uses prototype-based object orientation and provides the ability to extend types at runtime:

String.prototype.doubleLength = function() {
    return this.length * 2;
}

alert("foo".doubleLength());

An object delegates all access to attributes that it doesn't contain itself to its "prototype", another object. This can be used to implement inheritance, but is actually more powerful (even if more cumbersome):

/* "Constructor" */
function foo() {
    this.intValue = 5;
}

/* Create the prototype that includes everything
 * common to all objects created be the foo function.
 */
foo.prototype = {
    method: function() {
        alert(this.intValue);
    }
}

var f = new foo();
f.method();
Sebastian Rittau
Weird that no one thought of JSON !?
Allain Lalonde
+105  A: 

Maybe a little obvious to some...

Install Firebug and use console.log("hello"). So much better than using random alert();'s which I remember doing a lot a few years ago.

qui
Just don't forget to remove the console statements before releasing your code to others who may not have Firebug installed.
Chris Noe
function log(msg) { if(console) console.log(msg) else alert(msg) }
Josh
Even better, precede log statements with ';;;' and then minify takes care of it for you. (At least, the Perl module I use has that feature, and claims it's commonplace.)
Kev
Josh: That won't work as console is not defined. You could check typeof console !== "undefined" or window.console.
Eli Grey
Always include: if (typeof('console') == 'undefined') { console = { log: function() { } }; } then you can continue to use console.log, and it just does nothing.
gregmac
window.LOG = (typeof(console) != 'undefined') ? console.log : function() { ; } // Lets you use parameters too.
MiffTheFox
Josh: suggest changing to function log(msg) { if (console.log) console.log(msg) else alert(msg) }
Jason S
Or better yet: function log(msg) { if(console) console.log(msg) else alert(msg+"\nHey! Install Firebug so you don't get this annoying message!"); }
Jason S
to lighten the debugging day I tend to use quotes from my favourite comedy shows, e.g console.log('4 naan, Jeremy - that's insane!')
wheresrhys
Also, this is available in Chrome/Safari/IE w/o Firebug as well. But the semantics maybe a little different (what in the browser world is not?)
chakrit
A: 

JavaScript does have block scope! Use with and JSON:

function say(x) {document.write("x = '" + x + "'<br/>");}
var x = "outer scope";

with ({x: "inner scope"}) // Local instance of x masks global x
{
    x += " modified";
    say (x);
}

say(x);

It produces this output:

x = 'inner scope modified'
x = 'outer scope'

:)

dysfunctor
thats kind of misleading, its not really block scope. it'll just confuse some people here.
mattlant
"with" should be avoided. http://yuiblog.com/blog/2006/04/11/with-statement-considered-harmful/
Jason S
@mattlant: it is effectively block scope. How that block scope works is implementation detail. Also, this specific use of `with` is safe. Probably the only safe use of `with`. That's because the main complaint is that of ambiguity of weather or not the object passed to with has an attribute or not. In this case it is blindingly obvious what attributes belongs to the anonymous object.
slebetman
+7  A: 

One of my favorites is constructor type checking:

function getObjectType( obj ) {  
    return obj.constructor.name;  
}  

window.onload = function() {  
    alert( getObjectType( "Hello World!" ) );  
    function Cat() {  
        // some code here...  
    }  
    alert( getObjectType( new Cat() ) );  
}

So instead of the tired old [Object object] you often get with the typeof keyword, you can actually get real object types based upon the constructor.

Another one is using variable arguments as a way to "overload" functions. All you are doing is using an expression to detect the number of arguments and returning overloaded output:

function myFunction( message, iteration ) {  
    if ( arguments.length == 2 ) {  
        for ( i = 0; i < iteration; i++ ) {  
            alert( message );  
        }  
    } else {  
        alert( message );  
    }  
}  

window.onload = function() {  
    myFunction( "Hello World!", 3 );  
}

Finally, I would say assignment operator shorthand. I learned this from the source of the jQuery framework... the old way:

var a, b, c, d;
b = a;
c = b;
d = c;

The new (shorthand) way:

var a, b, c, d;
d = c = b = a;

Good fun :)

hal10001
It's not a good idea to rely on the constructor property, since it's mutable, it's not reliable. Once you start playing with with the prototype property it gets real easy to destroy the value of .constructor
Breton
+3  A: 

This one is super hidden, and only occasionally useful ;-)

You can use the prototype chain to create an object that delegates to another object without changing the original object.

var o1 = { foo: 1, bar: 'abc' };
function f() {}
f.prototype = o1;
o2 = new f();
assert( o2.foo === 1 );
assert( o2.bar === 'abc' );
o2.foo = 2;
o2.baz = true;
assert( o2.foo === 2 );
// o1 is unchanged by assignment to o2
assert( o1.foo === 1 );
assert( o2.baz );

This only covers 'simple' values on o1. If you modify an array or another object, then the prototype no longer 'protects' the original object. Beware anytime you have an {} or [] in a Class definition/prototype.

noah
+17  A: 

Timestamps in JavaScript:

// Usual Way
var d = new Date();
timestamp = d.getTime();

// Shorter Way
timestamp = (new Date()).getTime();

// Shortest Way
timestamp = +new Date();
Shortestest way: timestamp=+new Date;
Sjoerd Visscher
The shortest way is clever but hard to understand, as one might think you wanted to write += but mistakenly wrote =+
Rene Saarsoo
@Rene: Argh. I even got confused by your own statement, and 'fixed' the answer...
Adriano Varoli Piazza
Even shorter / less cryptic: just use "timestamp = new Date();". You can subtract timestamps because they have a valueOf() function that yields the integer timestamp. If you want to use the timestamp as an integer, either use "+timestamp" (short but cryptic) or "timestamp.valueOf()".
Jason S
Of course, with proper formatting / spacing, such ambiguity is avoided. Why is it so freaking hard to use proper spacing? Do NOT write "timestamp=+new Date();", of course that's confusing. Instead, write "timestamp = +new Date();".
ken
@ken: Who defines "proper"? Some people like less whitespace, some people like more. There may be a proper way for an organization or project, but not necessarily globally.
icktoofay
@icktoofay: Find me a coding standards spec anywhere that dictates, supports or condones code written like "timestamp=+new Date();". Alternatively, run that line through any of the vast number of JS formatters (aka beautifiers) and I'm willing to be not a single one will leave it spaceless. "Proper" may be subjective in theory, but in practice, it's very obvious what is and what is not "proper".
ken
@ken: Yes, of course `timestamp=+new Date();` isn't very clear and probably wouldn't be supported by any coding guidelines, but `something=123;` isn't uncommon, and can certainly be "proper" to people who are used to that style.
icktoofay
+5  A: 

Function.toString() (implicit):

function x() {
    alert("Hello World");
}
eval ("x = " + (x + "").replace(
    'Hello World',
    'STACK OVERFLOW BWAHAHA"); x("'));
x();
Jimmy
Keep in mind that `toSource()` is not standard. In your example you have `x + ""` which should normally be equivalent to `x.toString()`. I assume you meant to use `x.toSource()` instead?
Ates Goral
ahh, you caught me. I'm calling toString rather than ToSource, but according to http://developer.mozilla.org/En/Core_JavaScript_1.5_Reference:Objects:Function:toString -- Function.ToString() decompiles a function.
Jimmy
Yeah, toSource is useful for debugging in Mozilla. But, implicit toString can do cool (if not crazy) things, as you've noted.
palswim
+18  A: 

Private variables with a Public Interface

It uses a neat little trick with a self-calling function definition. Everything inside the object which is returned is available in the public interface, while everything else is private.

var test = function () {
    //private members
    var x = 1;
    var y = function () {
        return x * 2;
    };
    //public interface
    return {
        setx : function (newx) {
            x = newx;
        },
        gety : function () {
            return y();
        }
    }
}();

assert(undefined == test.x);
assert(undefined == test.y);
assert(2 == test.gety());
test.setx(5);
assert(10 == test.gety());
Chris MacDonald
this is called the module pattern, as was dubbed that by Eric Miraglia at http://yuiblog.com/blog/2007/06/12/module-pattern/I do think the name is misleading, should be called the Singleton Pattern or something like that. I might also add that public methods can also call other public methods by using 'this' object. I use this pattern all the time in my code to keep things organized and clean.
mikeycgto
+35  A: 

Methods (or functions) can be called on object that are not of the type they were designed to work with. This is great to call native (fast) methods on custom objects.

var listNodes = document.getElementsByTagName('a');
listNodes.sort(function(a, b){ ... });

This code crashes because listNodes is not an Array

Array.prototype.sort.apply(listNodes, [function(a, b){ ... }]);

This code works because listNodes defines enough array-like properties (length, [] operator) to be used by sort().

Vincent Robert
+29  A: 

Numbers are also objects. So you can do cool stuff like:

// convert to base 2
(5).toString(2) // returns "101"

// provide built in iteration
Number.prototype.times = function(funct){
  if(typeof funct === 'function') {
    for(var i = 0;i < Math.floor(this);i++) {
      funct(i);
    }
  }
  return this;
}


(5).times(function(i){
  string += i+" ";
});
// string now equals "0 1 2 3 4 "

var x = 1000;

x.times(function(i){
  document.body.innerHTML += '<p>paragraph #'+i+'</p>';
});
// adds 1000 parapraphs to the document
Zach
OMG! I didn't know about toString(radix)...
Ates Goral
Thanks. Nice ruby style method ;)
Niklaos
+8  A: 

You can do almost anything between parentheses if you separate statements with commas:

var z = ( x = "can you do crazy things with parenthesis", ( y = x.split(" "), [ y[1], y[0] ].concat( y.slice(2) ) ).join(" ") )

alert(x + "\n" + y + "\n" + z)

Output:

can you do crazy things with parenthesis
can,you,do,crazy,things,with,parenthesis
you can do crazy things with parenthesis
You can, but I'm pretty sure every sane JavaScript guy would want you drawn and quartered.
Allain Lalonde
Interesting possibilities for a code obfuscator.
Chris Noe
If you want it really obscure in an obfuscator, use Chinese or other unicode characters: function 喂(我) {alert(我)};
some
+7  A: 

The concept of truthy and falsy values. You don't need to do something like

if(someVar === undefined || someVar === null) ...

Simply do:

if(!someVar).

Every value has a corresponding boolean representation.

Rakesh Pai
You need to be careful with this one. Zero and the empty string convert to false as well.
Sjoerd Visscher
as a corollary, you should use if (!!x) to check for 'truthiness' instead of if (x)
HS
+6  A: 

You can execute an object's method on any object, regardless of whether it has that method or not. Of course it might not always work (if the method assumes the object has something it doesn't), but it can be extremely useful. For example:

function(){
    arguments.push('foo') // This errors, arguments is not a proper array and has no push method
    Array.prototype.push.apply(arguments, ['foo']) // Works!
}
Dan
I'm not sure if I love this usage or should be recoiling in fear!? :)
Allain Lalonde
also call - Array.prototype.push.call(arguments, 'foo' /*, arg2, arg3, etc*/);
Luke Schafer
+2  A: 

Joose is a nice object system if you would like Class-based OO that feels somewhat like CLOS.

// Create a class called Point
Class("Point", {
    has: {
        x: {
            is:   "rw",
            init: 0
        },
        y: {
            is:   "rw",
            init: 0
        }
    },
    methods: {
        clear: function () {
            this.setX(0);
            this.setY(0);
        }
    }
})

// Use the class
var point = new Point();
point.setX(10)
point.setY(20);
point.clear();
jrockway
+4  A: 

All your "hidden" features are right here on the Mozilla wiki: http://developer.mozilla.org/en/JavaScript.

There's the core JavaScript 1.5 reference, what's new in JavaScript 1.6, what's new in JavaScript 1.7, and also what's new in JavaScript 1.8. Look through all of those for examples that actually work and are not wrong.

omouse
+4  A: 

Visit:

Paste this JavaScript code into your web browser's address bar:

Enjoy the JavaScript disco show :-p

amix
Very nice! I love it :-)
webmat
+30  A: 

Some would call this a matter of taste, but:

aWizz = wizz || "default";
// same as: if (wizz) { aWizz = wizz; } else { aWizz = "default"; }

The trinary operator can be chained to act like Scheme's (cond ...):

(cond (predicate  (action  ...))
      (predicate2 (action2 ...))
      (#t         default ))

can be written as...

predicate  ? action( ... ) :
predicate2 ? action2( ... ) :
             default;

This is very "functional", as it branches your code without side effects. So instead of:

if (predicate) {
  foo = "one";
} else if (predicate2) {
  foo = "two";
} else {
  foo = "default";
}

You can write:

foo = predicate  ? "one" :
      predicate2 ? "two" :
                   "default";

Works nice with recursion, too :)

Andrey Fedorov
I like the predicate syntax you give. I've never thought of chaining like that. neat.
Allain Lalonde
Uh... JavaScript does have a switch() statement. :-)
staticsan
I'm not a big fan of switch statements - they're an artifact of C, not functional programming. In my example, a switch statement would still need three separate statements, all starting with "foo =" - obvious unecessary repetition.
Andrey Fedorov
Oh dear... So what's the hidden feature, exactly? The ability to mutilate code so it looks like another language? (I guess that's what they did with the Prototype library, too :)
harto
@harto: I think that JavaScript is flexible enough that it doesn't have that much of a defined style. Don't tell me you *never* use elements from other languages in your code. It's a matter of taste, as well.
Lucas Jones
@harto: the trick is to use the ternary op to do if-else on expressions. It's really neat that the same language feature that does the equivalent of if can also do if-else without modification.
Andrey Fedorov
I, for one, welcome the ternary operator.
thomasrutter
On re-reading, I'd like to point out that this isn't "making code look like another language", but actually simplifying the semantic meaning of the code: when you're trying to say "set foo to one of three things", that's a statement that should begin with "foo = ...", not "if".
Andrey Fedorov
This is great but how is this hidden? C has been around a long time and we've been doing this forever.
Hogan
+22  A: 

Off the top of my head...

Functions

arguments.callee refers to the function that hosts the "arguments" variable, so it can be used to recurse anonymous functions:

var recurse = function() {
  if (condition) arguments.callee(); //calls recurse() again
}

That's useful if you want to do something like this:

//do something to all array items within an array recursively
myArray.forEach(function(item) {
  if (item instanceof Array) item.forEach(arguments.callee)
  else {/*...*/}
})

Objects

An interesting thing about object members: they can have any string as their names:

//these are normal object members
var obj = {
  a : function() {},
  b : function() {}
}
//but we can do this too
var rules = {
  ".layout .widget" : function(element) {},
  "a[href]" : function(element) {}
}
/* 
this snippet searches the page for elements that
match the CSS selectors and applies the respective function to them:
*/
for (var item in rules) {
  var elements = document.querySelectorAll(rules[item]);
  for (var e, i = 0; e = elements[i++];) rules[item](e);
}

Strings

String.split can take regular expressions as parameters:

"hello world   with  spaces".split(/\s+/g);
//returns an array: ["hello", "world", "with", "spaces"]

String.replace can take a regular expression as a search parameter and a function as a replacement parameter:

var i = 1;
"foo bar baz ".replace(/\s+/g, function() {return i++});
//returns "foo1bar2baz3"
Leo
The things you mention... Are they implemented in all browsers?
roosteronacid
No. I'm pretty sure that Mosaic lacks most of them.
jsight
The javascript features, yes, they are implemented in all major browsers (IE6/7, FF2/3, Opera 9+, Safari2/3 and Chrome).document.querySelectorAll is not supported in all browsers yet (it's the W3C version of JQuery's $(), and Prototype's $$())
Leo
A: 

You can redefine large parts of the runtime environment on the fly, such as modifying the Array constructor or defining undefined. Not that you should, but it can be a powerful feature.

A somewhat less dangerous form of this is the addition of helper methods to existing objects. You can make IE6 "natively" support indexOf on arrays, for example.

phyzome
+53  A: 

Here are some interesting things:

  • Comparing NaN with anything (even NaN) is always false.
  • Array.sort can take a comparator function and is called by a quicksort-like driver (depends on implementation).
  • Regular expression "constants" can maintain state, like the last thing they matched.
  • Some versions of JavaScript allow you to access $0, $1, $2 members on a regex.
  • null is unlike anything else. It is neither an object, a boolean, a number, a string, nor undefined. It's a bit like an "alternate" undefined. (Note: typeof null == "object")
  • In the outermost context, this yields the otherwise unnameable [Global] object.
  • Declaring a variable with var, instead of just relying on automatic declaration of the variable gives the runtime a real chance of optimizing access to that variable
  • The with construct will destroy such optimzations
  • Variable names can contain Unicode characters.
  • JavaScript regular expressions are not actually regular. They are based on Perl's regexs, and it is possible to construct expressions with lookaheads that take a very, very long time to evaluate.
  • Blocks can be labeled and used as the targets of break. Loops can be labeled and used as the target of continue.
  • Arrays are not sparse. Setting the 1000th element of an otherwise empty array should fill it with undefined. (depends on implementation)
  • if (new Boolean(false)) {...} will execute the {...} block

[updated a little in response to good comments; please see comments]

David Leonard
null is actually an (special) object. `typeof null` returns "object".
Ates Goral
You can also get the [Global] object from anywhere like this: var glb = function () { return this; }();
Zilk
Global? Do you mean the window and self ?
some
Just got bitten by NaN===NaN === false.
some
The global object in javascript in a browser is the window object. When in the global scope doing: window.a == a;
Pim Jager
Array.sort is not implemented using a quicksort like driver, because it is necessary for the sort method to be able to handle absurd stuff like Math.random being used as a sort function, or comparison functions they modify what they are comparing. JavaScriptCore (eg. WebKit) uses AVL trees :-/
olliej
"Arrays are not sparse" depends on the implementation. If you set the value of a[1000] and look at a[999], then yes, it is `undefined`, but that is just the default value you get when looking for an index that doesn't exist. If you checked a[2000], that would also be `undefined`, but that doesn't mean you've allocated memory for it yet.In IE8, some arrays are dense, and some are sparse, depending on how the JScript engine felt at the time.Read more here: http://blogs.msdn.com/jscript/archive/2008/04/08/performance-optimization-of-arrays-part-ii.aspx
Chris Nielsen
@Ates: don't take what `typeof` returns for indicator of *anything*. That function is so broken and wildly inaccurate it's sickening.
SF.
@Ates and @SF: typeof returns "object" for a range of different types. But once you know how it works and what types identify as "object", it is at least reliable and consistent in its implementation.
thomasrutter
+1, but this could be improved so much with some links to examples, etc.
nickf
`typeof x === "object"` is quite unreliable but `typeof x === "function"` is still useful :)
chakrit
Comparing NaN with anything (even NaN) is always false.Does js represent NaNs as the actual floating point binary sequence? If so, then does comparing two identical NaNs equal true? Look up floating point representation if you're confused.
Razor Storm
@Razor Storm: JS uses IEEE 754 representation which has many bit patterns that are "Not-a-Number" values. JS's NaN represents all of them (ECMA 262-3 s4.3.23) indistinguishably (s8.5). All NaNs must compare as unequal (s11.9.3), so even 'identical' IEEE 754 NaNs will compare as unequal.
David Leonard
@David Leonard, ok cool thanks for your response, that makes sense.
Razor Storm
How do you label a block?
Casebash
+68  A: 

Also mentioned in Crockford's "Javascript: The Good Parts":

parseInt() is dangerous. If you pass it a string without informing it of the proper base it may return unexpected numbers. For example parseInt('010') returns 8, not 10. Passing a base to parseInt makes it work correctly:

parseInt('010') // returns 8! (in FF3)
parseInt('010', 10); // returns 10 because we've informed it which base to work with.
When doing code reviews, always look for this one. Leaving off the ", 10" is a common mistake that goes unnoticed in most testing.
Doug D
I got burned by the radix issue years ago and have never forgotten something so counter-intuitive as such. A great thing to point out since it'll make you wonder for a while.
JamesEggers
Why not use `Math.floor` or `Number`?`10 === Math.floor("010"); 10 === Number("010");`floats:`42 === Math.floor("42.69"); 42.69 === Number("42.69");`
just somebody
Might be worth adding to your JS utils file.. `___parseInt = parseInt;``parseInt = function (str, base) { return ___parseInt(str, base || 10) };`
Infinity
@Infinity If not a posted answer already, you should. I had no idea it just as simple as this to override built-in function behavior. Of course, it should make one look a bit more closely at any code packages they borrow from other sites. That harmless `parseInt` function could easily be made to do something not so harmless.
bob-the-destroyer
Ha.. you think parseInt could be dangerous? Try doing `undefined = 'foo'` at the top of your page..... Javascript is very flexible.. too flexible
Infinity
But indeed the answer has been posted so I just commented on there: http://stackoverflow.com/questions/61088/hidden-features-of-javascript/2303653#2303653
Infinity
@Infinity: what about redefining the fn to highlight the 'coding error' ? `__parseInt = parseInt; parseInt = function (str, base) { if (!base) throw new Error(69, "All your base belong to us"); return __parseInt(str, base); }`
JBRWilkinson
@just somebody: Math.floor behave differently to parseInt when dealing with negative numbers for example, which would mean checks for +-ness etc... Math.floor('-10.2') === -11; // true ; parseInt('-10.2') === -10; // true;
kwah
+14  A: 

There are several answers in this thread showing how to extend the Array object via its prototype. This is a BAD IDEA, because it breaks the for (i in a) statement.

So is it okay if you don't happen to use for (i in a) anywhere in your code? Well, only if your own code is the only code that you are running, which is not too likely inside a browser. I'm afraid that if folks start extending their Array objects like this, Stack Overflow will start overflowing with a bunch of mysterious JavaScript bugs.

See helpful details here.

Chris Noe
Very good advice!
roosteronacid
You shouldn't iterate over an array with for..in at all! Use the standard for() loop or the new forEach() method for arrays, and for..in strictly for iterating over object properties.
Zilk
Try to convince existing code of this advice ;)
Chris Noe
for( x in y) has never worked properly for arrays for me. I learned very quickly to use the long form of a for loop. I wouldn't let any code that uses for(in) on an array anywhere near any of my work. There's plenty of actual decent well written code I could use instead.
Breton
You just do not know JavaScript enough. It does not break the for-in loops, you construct them improperly. You have to check all the properties with "yourObject.hasOwnProperty(propertyName)" when you are iterating via for-in.
BYK
checking .hasOwnProperty may be ok for iterating over a dictionary-like object but it doesn't seem right to use that for an array.
HS
@statictype.org - yeah, it's not - that's the point. Just use an index var for iteration instead.
harto
+8  A: 

Here's a couple of shortcuts:

var a = []; // equivalent to new Array()
var o = {}; // equivalent to new Object()
travis
with var a = []; , you cannot create arrays of specified size. You will have to utilize var a = new Array(arraySize);
Rajat
Is there a measurable performance advantage to declaring an Array in JavaScript with a specified size?
travis
+54  A: 

I'd have to say self-executing functions.

(function() { alert("hi there");})();

Because Javascript doesn't have block scope, you can use a self-executing function if you want to define local variables:

(function() {
  var myvar = 2;
  alert(myvar);
})();

Here, myvar is does not interfere with or pollute the global scope, and disappears when the function terminates.

ScottKoon
What is this useful for? You get the same results from putting the alert outside the function.
Paul Marshall
It's not about the alert, it's about defining and executing a function all at once. You could have that self-executing function return a value and pass the function as a param to another function.
ScottKoon
@Paul it's good for encapsulation.
Mike Robinson
It's also good for block scoping.
Jim Hunziker
This can be good for creating and declaring an object and it's methods all in one step.
staticsan
Yeah, I enclose all my `.js` files in an anonymous self-executing function and attach anything I want globally accessible within it to the `window` object. Prevents global namespace pollution.
cdmckay
I added an example of why this is useful to this answer.
thomasrutter
This can be also used to rename variables: (function($){...})(jQuery) will access the global jQuery object as $.
Tgr
I disagree with the name; it's not "self-executing" at all.
hasen j
@hasen j: agreed.. it's just creating an anonymous function and then calling it immediately.
Claudiu
@Paul, agreeing with Mike; good for encapsulation; read Crockford's book for a good explanation.
Neil Whitaker
+5  A: 

The == operator has a very special property, that creates this disturbing equality (Yes, I know in other dynamic languages like Perl this behavior would be expected but JavaScript ususally does not try to be smart in comparisons):

>>> 1 == true
true
>>> 0 == false
true
>>> 2 == true
false
+9  A: 

Prevent annoying errors while testing in Internet Explorer when using console.log() for Firebug:

function log(message) {
    (console || { log: function(s) { alert(s); }).log(message);
}
Rob
it has nothing to do with the language... :)
galambalazs
"function(s) { alert(s); }" can simply be replaced by "alert"
mickael9
+6  A: 

let.

Counterpart to var's lack of block-scoping is let, introduced in JavaScript 1.7.

  • The let statement provides a way to associate values with variables within the scope of a block, without affecting the values of like-named variables outside the block.
  • The let expression lets you establish variables scoped only to a single expression.
  • The let definition defines variables whose scope is constrained to the block in which they're defined. This syntax is very much like the syntax used for var.
  • You can also use let to establish variables that exist only within the context of a for loop.
  function varTest() {
  var x = 31;
 if (true) {
   var x = 71;  // same variable!
   alert(x);  // 71
 }
 alert(x);  // 71
  }

  function letTest() {
 let x = 31;
 if (true) {
   let x = 71;  // different variable
   alert(x);  // 71
 }
 alert(x);  // 31
  }

As of 2008, JavaScript 1.7 is supported in FireFox 2.0+ and Safari 3.x.

eed3si9n
+5  A: 

Generators and Iterators (works only in Firefox 2+ and Safari).

function fib() {
  var i = 0, j = 1;
  while (true) {
 yield i;
 var t = i;
 i = j;
 j += t;
  }
}

var g = fib();
for (var i = 0; i < 10; i++) {
  document.write(g.next() + "<br>\n");
}

The function containing the yield keyword is a generator. When you call it, its formal parameters are bound to actual arguments, but its body isn't actually evaluated. Instead, a generator-iterator is returned. Each call to the generator-iterator's next() method performs another pass through the iterative algorithm. Each step's value is the value specified by the yield keyword. Think of yield as the generator-iterator version of return, indicating the boundary between each iteration of the algorithm. Each time you call next(), the generator code resumes from the statement following the yield.

In normal usage, iterator objects are "invisible"; you won't need to operate on them explicitly, but will instead use JavaScript's for...in and for each...in statements to loop naturally over the keys and/or values of objects.

var objectWithIterator = getObjectSomehow();

for (var i in objectWithIterator)
{
  document.write(objectWithIterator[i] + "<br>\n");
}
eed3si9n
+44  A: 

To properly remove a property from an object, you should delete the property instead of just setting it to undefined:

var obj = { prop1: 42, prop2: 43 };

obj.prop2 = undefined;

for (var key in obj) {
    ...

The property prop2 will still be part of the iteration. If you want to completely get rid of prop2, you should instead do:

delete obj.prop2;

The property prop2 will no longer will make an appearance when you're iterating through the properties.

Ates Goral
Note that the delete statement is not without its browser-specific quirks. For instance this will fail with a big error if you try it in IE and the object is not a native JS object (even when deleting a property you added yourself). It's also not intended for deleting a variable, as in delete myvar; but I think that does work in some browsers. The code in the above answer seems pretty safe though.
thomasrutter
+83  A: 

If you're Googling for a decent JavaScript reference on a given topic, include the "mdc" keyword in your query and your first results will be from the Mozilla Developer Center. I don't carry any offline references or books with me. I always use the "mdc" keyword trick to directly get to what I'm looking for. For example:

Google: javascript array sort mdc
(in most cases you may omit "javascript")

Ates Goral
What did we do to deserve being linked to LMGTFY...
MiseryIndex
for example what?
simon
Fixed Google search link.
Ates Goral
Wow, great resource. Instantly better than crappy w3schools...
DisgruntledGoat
You don't even need to Google it, if you're on Firefox: just type "array mdc" into the address bar and hit Enter.
musicfreak
the best part is how this stack overflow question is on the first page of results :)
Jiaaro
+6  A: 

If you blindly eval() a JSON string to deserialize it, you may run into problems:

  1. It's not secure. The string may contain malicious function calls!
  2. If you don't enclose the JSON string in parentheses, property names can be mistaken as labels, resulting in unexpected behaviour or a syntax error:

    eval("{ \"foo\": 42 }"); // syntax error: invalid label
    eval("({ \"foo\": 42 })"); // OK
    
Ates Goral
A: 

function l(f,n){n&&l(f,n-1,f(n));}

l( function( loop ){ alert( loop ); }, 5 );

alerts 5, 4, 3, 2, 1

It makes sense but...I would never employ you.
Improfane
+1  A: 

To convert a floating point number to an integer, you can use one of the following cryptic hacks (please don't):

  1. 3.14 >> 0 (via http://stackoverflow.com/questions/173070/29999999999999999-5)
  2. 3.14 | 0 (via http://stackoverflow.com/questions/131406/what-is-the-best-method-to-convert-to-an-integer-in-javascript)
  3. 3.14 & -1
  4. 3.14 ^ 0

Basically, applying any binary operation on the float that won't change the final value (i.e. identity function) ends up converting the float to an integer.

Ates Goral
Please just use Math.floor().
Jason S
...and Math.PI!
ken
+4  A: 

jQuery and JavaScript:

Variable-names can contain a number of odd characters. I use the $ character to identify variables containing jQuery objects:

var $links = $("a");

$links.hide();

jQuery's pattern of chaining objects is quite nice, but applying this pattern can get a bit confusing. Fortunately JavaScript allows you to break lines, like so:

$("a")
.hide()
.fadeIn()
.fadeOut()
.hide();

General JavaScript:

I find it useful to emulate scope by using self-executing functions:

function test()
{
    // scope of test()

    (function()
    {
        // scope inside the scope of test()
    }());

    // scope of test()
}
roosteronacid
If you want it really odd:function 喂(我) {alert(我)};喂("world");
some
+5  A: 

Function statements and function expressions are handled differently.

function blarg(a) {return a;} // statement
bleep = function(b) {return b;} //expression

All function statements are parsed before code is run - a function at the bottom of a JavaScript file will be available in the first statement. On the other hand, it won't be able to take advantage of certain dynamic context, such as surrounding with statements - the with hasn't been executed when the function is parsed.

Function expressions execute inline, right where they are encountered. They aren't available before that time, but they can take advantage of dynamic context.

Justin Love
+21  A: 

Prototypal inheritance (popularized by Douglas Crockford) completely revolutionizes the way you think about loads of things in Javascript.

Object.beget = (function(Function){
    return function(Object){
        Function.prototype = Object;
        return new Function;
    }
})(function(){});

It's a killer! Pity how almost no one uses it.

It allows you to "beget" new instances of any object, extend them, while maintaining a (live) prototypical inheritance link to their other properties. Example:

var A = {
  foo : 'greetings'
};  
var B = Object.beget(A);

alert(B.foo);     // 'greetings'

// changes and additionns to A are reflected in B
A.foo = 'hello';
alert(B.foo);     // 'hello'

A.bar = 'world';
alert(B.bar);     // 'world'


// ...but not the other way around
B.foo = 'wazzap';
alert(A.foo);     // 'hello'

B.bar = 'universe';
alert(A.bar);     // 'world'
Már Örlygsson
+4  A: 

window.name's value persists across page changes, can be read by the parent window if in same domain (if in an iframe, use document.getElementById("your frame's ID").contentWindow.name to access it), and is limited only by available memory.

bbrown
+12  A: 

Be sure to use the hasOwnProperty method when iterating through an object's properties:

for (p in anObject) {
    if (anObject.hasOwnProperty(p)) {
        //Do stuff with p here
    }
}

This is done so that you will only access the direct properties of anObject, and not use the properties that are down the prototype chain.

Andreas Grech
+15  A: 

When you want to remove an element from an array, one can use the delete operator, as such:

var numbers = [1,2,3,4,5];
delete numbers[3];
//numbers is now [1,2,3,undefined,5]

As you can see, the element was removed, but a hole was left in the array since the element was replaced with an undefined value.

Thus, to work around this problem, instead of using delete, use the splice array method...as such:

var numbers = [1,2,3,4,5];
numbers.splice(3,1);
//numbers is now [1,2,3,5]

The first argument of splice is an ordinal in the array [index], and the second is the number of elements to delete.

Andreas Grech
Remember "undefined"
pramodc84
+5  A: 

Microsofts gift to JavaScript: AJAX

AJAXCall('http://www.abcd.com/')

function AJAXCall(url) {
 var client = new XMLHttpRequest();
 client.onreadystatechange = handlerFunc;
 client.open("GET", url);
 client.send();
}

function handlerFunc() {
 if(this.readyState == 4 && this.status == 200) {
 if(this.responseXML != null)
   document.write(this.responseXML)
 }
}
Binoj Antony
+3  A: 

Large loops are faster in a while condition and backwards - that is, if the order of the loop doesn't matter to you. In about 50% of my code, it usually doesn't.

i.e.

var i, len = 100000;

for (var i = 0; i < len; i++) {
  // do stuff
}

Is slower than:

i = len;
while (i--) {
  // do stuff
}
Remy Sharp
Do you any articles explaining this result? Would be interesting to get some more info why it happens.
Alex
Is it so in every Javascript implementation?
voyager
I'm guessing the second one is faster because it doesn't have to evaluate i < len every turn which requires 100,000 to be compared to i. This is probably faster than checking if i is 0 or not.
Improfane
-1; do you have any proof of this? which implementation are you using? I just tried the following code (replace pipe | symbols with newlines) on jsdb which uses Spidermonkey (Firefox javascript engine) and it is essentially the same execution time.var i, len=15000000; |d1=new Date(); for (var i = 0; i < len; i++) {}; new Date()-d1 |d1=new Date(); i=len; while(i--) {}; new Date()-d1
Jason S
@Jason - the benchmark is IE since that's the dominant browser - as the new browsers compete we're seeing awesome improvements in the JS engines, so of course you'll see that the engines will improve on this pattern, but you *have* to cross browser test your optimisation when the milliseconds count. So, did you check this code in the other browsers too?
Remy Sharp
This is true when you are not doing stuff, but when you are changing an array, it works faster forwards.
tmim
+1  A: 

There is also an almost unknown JavaScript syntax:

var a;
a=alert(5),7;
alert(a);    // alerts undefined
a=7,alert(5);
alert(a);    // alerts 7

a=(3,6);
alert(a);    // alerts 6

More about this here.

Wilq32
+19  A: 

You can use objects instead of switches most of the time.

function getInnerText(o){
    return o === null? null : {
        string: o,
        array: o.map(innerText).join(""),
        object:innerText(o["childNodes"])
    }[typeof o];
}
Breton
This is a very cool idea.
Improfane
That's how Python gets by without a switch statement.
outis
+19  A: 

You may catch exceptions depending on their type. Quoted from MDC:

try {
   myroutine(); // may throw three exceptions
} catch (e if e instanceof TypeError) {
   // statements to handle TypeError exceptions
} catch (e if e instanceof RangeError) {
   // statements to handle RangeError exceptions
} catch (e if e instanceof EvalError) {
   // statements to handle EvalError exceptions
} catch (e) {
   // statements to handle any unspecified exceptions
   logMyErrors(e); // pass exception object to error handler
}

NOTE: Conditional catch clauses are a Netscape (and hence Mozilla/Firefox) extension that is not part of the ECMAScript specification and hence cannot be relied upon except on particular browsers.

Ionuț G. Stan
I couldn't help it: catch (me if youCan)
Ates Goral
Read the note from the MDC page you cited: conditional catch clauses are a Netscape (and hence Mozilla/Firefox) extension that is not part of the ECMAScript specification and hence cannot be relied upon except on particular browsers.
Jason S
Jason, yes you're right. Good to know about this feature nevertheless.
Ionuț G. Stan
+6  A: 

You can turn "any* object with integer properties, and a length property into an array proper, and thus endow it with all array methods such as push, pop, splice, map, filter, reduce, etc.

Array.prototype.slice.call({"0":"foo", "1":"bar", 2:"baz", "length":3 })

// returns ["foo", "bar", "baz"]

This works with jQuery objects, html collections, and Array objects from other frames (as one possible solution to the whole array type thing). I say, if it's got a length property, you can turn it into an array and it doesn't matter. There's lots of non array objects with a length property, beyond the arguments object.

Breton
+3  A: 

Syntactic sugar: in-line for-loop closures

var i;

for (i = 0; i < 10; i++) (function ()
{
    // do something with i
}());

Breaks almost all of Douglas Crockford's code-conventions, but I think it's quite nice to look at, never the less :)


Alternative:

var i;

for (i = 0; i < 10; i++) (function (j)
{
    // do something with j
}(i));
roosteronacid
You know, you don't really need the i as an argument to the function. Removing the i makes it a closure. Right now it isn't one.
Ionuț G. Stan
Brainfart. Updated the answer. Thanks :)
roosteronacid
Sorry, I meant both the argument and the parameter :)
Ionuț G. Stan
Isn't this making a function every iteration of the loop?
Improfane
+2  A: 

This seems to only work on Firefox (SpiderMonkey). Inside a function:

  • arguments[-2] gives the number of arguments (same as arguments.length)
  • arguments[-3] gives the function that was called (same as arguments.callee)
Ates Goral
+2  A: 

Existence checks. So often I see stuff like this

var a = [0, 1, 2];

// code that might clear the array.

if (a.length > 0) {
 // do something
}

instead for example just do this:

var a = [0, 1, 2];

// code that might clear the array.

if (a.length) { // if length is not equal to 0, this will be true
 // do something
}

There's all kinds of existence checks you can do, but this was just a simple example to illustrate a point

Here's an example on how to use a default value.

function(someArgument) {
      someArgument = someArgument || "This is the deault value";
}

That's my two cents. There's other nuggets, but that's it for now.

nickyt
Warning: someArgument will get overridden if it evaluates as false (which includes the values 0, NaN, false, "", and null, as well as an omission of the argument)
Jason S
+7  A: 

You never have to use eval() to assemble global variable names.

That is, if you have several globals (for whatever reason) named spec_grapes, spec_apples, you do not have to access them with eval("spec_" + var).

All globals are members of window[], so you can do window["spec_" + var].

Lucent
Also you can shorten "if (typeof myvar != 'undefined')" to "if (window.myvar)"
BarelyFitz
Remember this is *only* on a browser's javascript engine. You could be running a stand alone Javascript engine. Server-side javascript anyone? -- Just nitpicking, I know...
voyager
@voyager: I agree - http://jaxer.org is COOL!
Lucas Jones
@BarelyFitz: Not true. The variable window.myvar could have any of the following values: 0, false, "", null, or NaN. (there may be others but I think I've covered them.)
Jason S
function getGlobal() { return (function inner() { return this; })(); };- even 'apply', 'call' and prototype shenanigans can't make that not return the global scope (which on the web is 'window')
Luke Schafer
+3  A: 

You can iterate over Arrays using "for in"

Mark Cidade pointed out the usefullness of the "for in" loop :

// creating an object (the short way, to use it like a hashmap)
var diner = {
"fruit":"apple"
"veggetable"="bean"
}

// looping over its properties
for (meal_name in diner ) {
    document.write(meal_name+"<br \n>");
}

Result :

fruit
veggetable

But there is more. Since you can use an object like an associative array, you can process keys and values, just like a foreach loop :

// looping over its properties and values
for (meal_name in diner ) {
    document.write(meal_name+" : "+diner[meal_name]+"<br \n>");
}

Result :

fruit : apple
veggetable : bean

And since Array are objects too, you can iterate other array the exact same way :

var my_array = ['a', 'b', 'c'];
for (index in my_array ) {
    document.write(index+" : "+my_array[index]+"<br \n>");
}

Result :

0 : a
1 : b
3 : c

You can remove easily an known element from an array

var arr = ['a', 'b', 'c', 'd'];
var pos = arr.indexOf('c');
pos > -1 && arr.splice( pos, 1 );

You can shuffle easily an array

arr.sort(function() Math.random() > 0.5 ? 1 : -1);
e-satis
+1 for the nice array shuffle
Peter Perháč
-1 for the array shuffle. The sort() function's argument should always yield a consistent ordering. You have no proof that the results will show up as a random distribution; it depends on the implementation of sort().
Jason S
If you really want a random sort, use a function(a,b) that compares a "random" function g(x,k) applied to a and b (compare g(a,k) and g(b,k)) where k is some parameter held constant at least during the duration of the sort, and g() is a hash function of some sort.
Jason S
Or better yet, just use a Fisher-Yates shuffle. http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Jason S
Interesting. Thanks Jason.
e-satis
You can doesn't mean you should...
galambalazs
+7  A: 

The parentheses are optional when creating new "objects".

function Animal () {

}

var animal = new Animal();
var animal = new Animal;

Same thing.

Dave
is that part of ECMAScript or just the Mozilla Spidermonkey engine? (it works with the Spidermonkey shell)
Jason S
not sure, I've just taken advantage of this assumption for some time now. works in IE, IIS too
Dave
I like to leave the parentheses there because it reminds me that you are actually calling a function (and 'new' makes it implicitly return 'this').
Nick
+17  A: 

You can assign local variables using [] on the left hand side. Comes in handy if you want to return more than one value from a function without creating a needless array.

function fn(){
    var cat = "meow";
    var dog = "woof";
    return [cat,dog];
};

var [cat,dog] = fn();  // Handy!

alert(cat);
alert(dog);

It's part of core JS but somehow I never realized till this year.

username
not supported by IE, except this small issue this is an interesting feature.
Kamarey
This is "destructuring assignment"; I believe it's only supported in Firefox versions running JavaScript 1.7 and later. It definitely causes an error in Opera 10 and Chrome 3 as well as IE. See https://developer.mozilla.org/en/New_in_JavaScript_1.7#Destructuring_assignment
NickFitz
I'd love to see syntax like this in more languages, like C#.
Greg
In the meantime, this is pretty much as good:`function fn(){ return {cat:"meow",dog:"woof"}; // Handy!};var snd = fn();alert(snd.cat);alert(snd.dog);`
Plynx
+1  A: 

JavaScript tips or the jslibs project.

Gumbo
A: 

Maybe one of the lesser-known ones:

arguments.callee.caller + Function#toString()

function called(){
    alert("Go called by:\n"+arguments.callee.caller.toString());
}

function iDoTheCall(){
    called();
}

iDoTheCall();

Prints out the source code of iDoTheCall -- Deprecated, but can be useful sometimes when alerting is your only option....

sschuth
+1  A: 

You can bind a JavaScript object as a HTML element attribute.

<div id="jsTest">Klick Me</div>
<script type="text/javascript">
    var someVariable = 'I was klicked';
    var divElement = document.getElementById('jsTest');
    // binding function/object or anything as attribute
    divElement.controller = function() { someVariable += '*'; alert('You can change instance data:\n' + someVariable ); };
    var onclickFunct = new Function( 'this.controller();' ); // Works in Firefox and Internet Explorer.
    divElement.onclick = onclickFunct;
</script>
pawelsto
A: 

An interesting way to make Singleton-like objects with public / private methods (I saw this once in a jQuery plugin):

var Car = function() {

 function Engine() {

  function start() {   
  }

  function stop() {   
  }

  function internal1() {   
  }

  return {
   start : start,
   stop : stop
  }
 }();

 function start() {
  Engine.start();
  // other startup code
 }

 function stop() {
  Engine.stop();
  // other stop code
 }

 return {
  start : start,
  stop : stop 
 }
}();

The internal objects has public methods that only internal objects can interface with allowing the main object public methods for accessing the internal public methods.

I don't have enough Rep to edit, but the code could use some indenting at the start and the end, so the code block starts and end correctly.
voyager
This is wrong on several counts: 1. `function() {} ()` is a syntax error, you need `(function() {}) ()` instead; 2. `Engine.start` (or `stop`) is not visible, you would have to assign the return value of the function to the `Engine` variable (not the function itself) for this to work; 3. the example has nothing to do with singletons.
Tgr
+5  A: 

If you're attempting to sandbox javascript code, and disable every possible way to evaluate strings into javascript code, be aware that blocking all the obvious eval/document.write/new Function/setTimeout/setInterval/innerHTML and other DOM manipulations isn't enough.

Given any object o, o.constructor.constructor("alert('hi')")() will bring up an alert dialog with the word "hi" in it.

You could rewrite it as

var Z="constructor";
Z[Z][Z]("alert('hi')")();

Fun stuff.

Metal
This is more of a hidden "gotcha" than a hidden feature but it's extremely interesting considering I've tried to block things like `eval` before. Very interesting indeed :-) +1
JJ
You could usefully mention here that the -reason- for this is that the constructor of any object is always some function, and that the constructor of that function will always be `Function` - the function constructor which can construct functions from strings. `Function(str)` effectively returns `function() { eval(str) }`.
James Hart
+6  A: 

The fastest loops in JavaScript are while(i--) ones. In all browsers. So if it's not that important for order in which elements of your loop get processed you should be using while(i--) form:

var names = new Array(1024), i = names.length;
while(i--)
  names[i] = "John" + i;

Also, if you have to use for() loop going forward, remember always to cache .length property:

var birds = new Array(1024); 
for(var i = 0, j = birds.length; i < j; i++)
  birds[i].fly();

To join large strings use Arrays (it's faster):

var largeString = new Array(1024), i = largeString.length;
while(i--) {
  // It's faster than for() loop with largeString.push(), obviously :)
  largeString[i] = i.toString(16);
}

largeString = largeString.join("");

It's much faster than largeString += "something" inside an loop.

I've been using the for-loop variant of your `while(i--)` for some time now: `for (var i=names.length;i--;) {...`
slebetman
I don't agree. In firefox, `(function(){var a=new Array(10000),i=10000;while(--i){a[i]=i}})()` takes about 7 milliseconds whereas (function(){var a=new Array(10000);for(var i=0;i<10000;i++){a[i]=i}})() takes about 2 milliseconds.
tmim
A: 

Look for valid variables, return the first one (G.valid(var1,var2,var3)):

    valid : function(){                                                     
            var     i,                                                      
                    args = Array.prototype.slice.call(arguments);           
            for(i in args) {                                                
                    if(args[i] !== undefined) {                             
                            return args[i];                                 
                    }                                                       
            }                                                               
            return "";                                                      
    },

Turn hh:mm:ss to (number)h (number)m:

    var time=/(\d{2}):(\d{2}):(\d{2})/;                                                                                            
    return t.replace(time, function(str, p1, p2, p3, offset, s) {                                                                  
            var     h=parseInt(p1),                                                                                                
                    m=parseInt(p2),                                                                                                
                    ret = "";                                                                                                      
            if(h > 0) {                                                                                                            
                    ret = h + "h ";                                                                                                
            }                                                                                                                      
            return ret + m + "m";                                                                                                  
    });

Deal with money in pennies....

Do an action on enter:

onEnter(element, callback):

    onEnter: function(div, callback) {                                                                                             
            div.onkeyup(function(e){                                                                                              
                    var keycode;                                                                                                   
                    if (window.event) keycode = window.event.keyCode;                                                              
                    else if (e) keycode = e.which;                                                                                 
                    else return true;                                                                                              

                    if (keycode == 13) {                                                                                           
                            callback.apply(this);                                                                                  
                    }                                                                                                              
            });                                                                                                                    
    },

serialize an object's keys, discarding its values

    sObj : function (o) {                                                                                                          
            var     ret = [],                                                                                                      
                    i;                                                                                                             
            for(i in o) {                                                                                                          
                    ret.push(i);                                                                                                   
            }                                                                                                                      
            return ret;                                                                                                            
    },
A: 

The coalescing operator is very cool and makes for some clean, concise code, especially when you chain it together: a || b || c || "default"; The gotcha is that since it works by evaluating to bool rather than null, if values that evaluate to false are valid, they'll often times get over looked. Not to worry, in these cases just revert to the good ol' ternary operator.

I often see code that has given up and used global instead of static variables, so here's how (in an example of what I suppose you could call a generic singleton factory):

var getInstance = function(objectName) {
  if ( !getInstance.instances ) {
    getInstance.instances = {};
  }

  if ( !getInstance.instances[objectName] ) {
    getInstance.instances[objectName] = new window[objectName];
  }

  return getInstance.instances[objectName];
};

Also, note the new window[objectName]; which was the key to generically instantiating objects by name. I just figured that out 2 months ago.

In the same spirit, when working with the DOM, I often bury functioning parameters and/or flags into DOM nodes when I first initialize whatever functionality I'm adding. I'll add an example if someone squawks.

Surprisingly, no one on the first page has mentioned hasOwnProperty, which is a shame. When using in for iteration, it's good, defensive programming to use the hasOwnProperty method on the container being iterated over to make sure that the member names being used are the ones that you expect.

var x = [1,2,3];
for ( i in x ) {
    if ( !x.hasOwnProperty(i) )  { continue; }
    console.log(i, x[i]);
}

Read here for more on this.

Lastly, with is almost always a bad idea.

Justin Johnson
A: 

Testing that object attributes are defined before they are used can be tedious:

// This can throw an error is some or deep or nested are undefined
some.deep.nested.attribute = somevalue;

// But testing them is tedious
if (typeof(some) != 'undefined') {
   if (typeof(some.deep) != 'undefined') {
       etc...
   }
}

However:

// Simples!
try { some.deep.nested.attribute = somevalue; }
catch (e) { alert('Ooooh'); }
Justin Johnson
Don't use try/catch when you don't need to. You don't need to here. Do it like JJ says.
ken
Bill Barry
+1  A: 

You can make "classes" that have private (inaccessible outside the "class" definition) static and non-static members, in addition to public members, using closures.

Note that there are two types of public members in the code below. Instance-specific (defined in the constructor) that have access to private instance members, and shared members (defined in the prototype object) that only have access to private static members.

var MyClass = (function () {
    // private static
    var nextId = 1;

    // constructor
    var cls = function () {
     // private
     var id = nextId++;
     var name = 'Unknown';

     // public (this instance only)
     this.get_id = function () { return id; };

     this.get_name = function () { return name; };
     this.set_name = function (value) {
      if (typeof value != 'string')
       throw 'Name must be a string';
      if (value.length < 2 || value.length > 20)
       throw 'Name must be 2-20 characters long.';
      name = value;
     };
    };

    // public static
    cls.get_nextId = function () {
     return nextId;
    };

    // public (shared across instances)
    cls.prototype = {
     announce: function () {
      alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
            'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
     }
    };

    return cls;
})();

To test this code:

var mc1 = new MyClass();
mc1.set_name('Bob');

var mc2 = new MyClass();
mc2.set_name('Anne');

mc1.announce();
mc2.announce();

If you have Firebug you'll find that there is no way to get access to the private members other than to set a breakpoint inside the closure that defines them.

This pattern is very useful when defining classes that need strict validation on values, and complete control of state changes.

To extend this class, you would put MyClass.call(this); at the top of the constructor in the extending class. You would also need to copy the MyClass.prototype object (don't reuse it, as you would change the members of MyClass as well.

If you were to replace the announce method, you would call MyClass.announce from it like so: MyClass.prototype.announce.call(this);

Blixt
+4  A: 

JavaScript typeof operator used with arrays or nulls always returns object value which in some cases may not be what programmer would expect.

Here's a function that will return proper values for those items as well. Array recognition was copied from Douglas Crockford's book "JavaScript: The Good Parts".

function typeOf (value) {
    var type = typeof value;
    if (type === 'object') {
        if (value === null) {
             type = 'null';
        } else if (typeof value.length === 'number' && 
            typeof value.splice === 'function' && 
            !value.propertyIsEnumerable('length')) {
            type = 'array';
        }
    }
    return type;
}
RaYell
[] instanceof Array
Luke Schafer
Yeah, I guess it could be done like that. But as I mentioned this is copied from a book.
RaYell
which is why i've never been a fan of crockford - his code is always too obtuse
Luke Schafer
+1  A: 

Using Function.apply to specify the object that the function will work on:

Suppose you have the class

function myClass(){
 this.fun = function(){
   do something;
 };
}

if later you do:

var a = new myClass();
var b = new myClass();

myClass.fun.apply(b); //this will be like b.fun();

You can even specify an array of call parameters as a secondo argument

look this: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function/apply

gotch4
+1  A: 

My first submission is not so much a hidden feature as a rarely used application of the property re-definition feature. Because you can redefine an object's methods, you can cache the result of a method call, which is useful if the calculation is expensive and you want lazy evaluation. This gives the simplest form of memoization.

function Circle(r) {
    this.setR(r);
}

Circle.prototype = {
  recalcArea: function() {
        this.area=function() {
            area = this.r * this.r * Math.PI;
            this.area = function() {return area;}
            return area;
        }
    },
  setR: function (r) {
      this.r = r;
      this.invalidateR();
    },
  invalidateR: function() {
        this.recalcArea();
    }
}

Refactor the code that caches the result into a method and you get:

Object.prototype.cacheResult = function(name, _get) {
  this[name] = function() {
    var result = _get.apply(this, arguments);
    this[name] = function() {
      return result;
    }
    return result;
  };
};

function Circle(r) {
    this.setR(r);
}

Circle.prototype = {
  recalcArea: function() {
        this.cacheResult('area', function() { return this.r * this.r * Math.PI; });
    },
  setR: function (r) {
      this.r = r;
      this.invalidateR();
    },
  invalidateR: function() {
        this.recalcArea();
    }
}

If you want a memoized function, you can have that instead. Property re-definition isn't involved.

Object.prototype.memoize = function(name, implementation) {
    this[name] = function() {
        var argStr = Array.toString.call(arguments);
        if (typeof(this[name].memo[argStr]) == 'undefined') {
            this[name].memo[argStr] = implementation.apply(this, arguments);
        }
        return this[name].memo[argStr];
    }
};

Note that this relies on the standard array toString conversion and often won't work properly. Fixing it is left as an exercise for the reader.

My second submission is getters and setters. I'm surprised they haven't been mentioned yet. Because the official standard differs from the de facto standard (defineProperty vs. define[GS]etter) and Internet Explorer barely supports the official standard, they aren't generally useful. Maybe that's why they weren't mentioned. Note that you can combine getters and result caching rather nicely:

Object.prototype.defineCacher = function(name, _get) {
    this.__defineGetter__(name, function() {
        var result = _get.call(this);
        this.__defineGetter__(name, function() { return result; });
        return result;
    })
};

function Circle(r) {
    this.r = r;
}

Circle.prototype = {
  invalidateR: function() {
        this.recalcArea();
    },
  recalcArea: function() {
        this.defineCacher('area', function() {return this.r * this.r * Math.PI; });
    },
  get r() { return this._r; }
  set r(r) { this._r = r; this.invalidateR(); }
}

var unit = new Circle(1);
unit.area;

Efficiently combining getters, setters and result caching is a little messier because you have to prevent the invalidation or do without automatic invalidation on set, which is what the following example does. It's mostly an issue if changing one property will invalidate multiple others (imagine there's a "diameter" property in these examples).

Object.prototype.defineRecalcer = function(name, _get) {
  var recalcFunc;
  this[recalcFunc='recalc'+name.toCapitalized()] = function() {
    this.defineCacher(name, _get);
  };
  this[recalcFunc]();
  this.__defineSetter__(name, function(value) {
      _set.call(this, value);
      this.__defineGetter__(name, function() {return value; });
  });
};

function Circle(r) {
    this.defineRecalcer('area',
             function() {return this.r * this.r * Math.PI;},
             function(area) {this._r = Math.sqrt(area / Math.PI);},
    );
    this.r = r;
}

Circle.prototype = {
  invalidateR: function() {
        this.recalcArea();
    },
  get r() { return this._r; }
  set r(r) { this._r = r; this.invalidateR(); }
}
outis
+5  A: 

The Module Pattern

<script type="text/javascript">
(function() {

function init() {
  // ...
}

window.onload = init;
})();
</script>

Variables and functions declared without the var statement or outside of a function will be defined in the global scope. If a variable/function of the same name already exists it will be silently overridden, which can lead to very hard to find errors. A common solution is to wrap the whole code body into an anonymous function and immediately execute it. This way all variables/functions are defined in the scope of the anonymous function and don't leak into the global scope.

To explicitly define a variable/function in the global scope they have to be prefixed with window:

window.GLOBAL_VAR = 12;
window.global_function = function() {};
Fabian Jakobs
+2  A: 

Namespaces

In larger JavaScript applications or frameworks it can be useful to organize the code in namespaces. JavaScript doesn't have a module or namespace concept buildin but it is easy to emulate using JavaScript objects. This would create a namespace called nsand attaches the function footo it.

if (!window.ns) {
  window.ns = {};
}

window.ns.foo = function() {};

It is common to use the same global namespace prefix throughout a project and use sub namespaces for each JavaScript file. The name of the sub namespace often matches the file's name.

The header of a file called ns/button.jscould look like this:

if (!window.ns) {
  window.ns = {};
}
if (!window.ns.button) {
  window.ns.button = {};
}

// attach methods to the ns.button namespace
window.ns.button.create = function() {};
Fabian Jakobs
+1  A: 

Here's a simple way of thinking about 'this'. 'This' inside a function will refer to future object instances of the function, usually created with operator new. So clearly 'this' of an inner function will never refer to an instance of an outer function.

The above should keep one out of trouble. But there are more complicated things you can do with 'this.'


Example 1:


     function DriveIn()
     {
          this.car = 'Honda';
          alert(this.food);  //'food' is the attribute of a future object 
                             //and DriveIn does not define it.
     }

     var A = {food:'chili', q:DriveIn};  //create object A whose q attribute 
                                         //is the function DriveIn;

     alert(A.car); //displays 'undefined' 
     A.q();        //displays 'chili' but also defines this.car.
     alert(A.car); //displays 'Honda' 


The Rule of This:

Whenever a function is called as the attribute of an object, any occurrence of 'this' inside the function (but outside any inner functions) refers to the object.

We need to make clear that "The Rule of This" applies even when operator new is used. Behind the scenes new attaches 'this' to the object through the object's constructor attribute.


Example 2:


      function Insect ()
      {
           this.bug = "bee";
           this.bugFood = function()
           {
               alert("nectar");
           }
       }

      var B = new Insect();
      alert(B.constructor); //displays "Insect"; By "The Rule of This" any
                            //ocurrence of 'this' inside Insect now refers 
                            //to B.    

To make this even clearer, we can create an Insect instance without using operator new.

Example 3:

   
    var C = {constructor:Insect};  //Assign the constructor attribute of C, 
                                   //the value Insect.
    C.constructor();               //Call Insect through the attribute. 
                                   //C is now an Insect instance as though it 
                                   //were created with operator new. [*]
    alert(C.bug);                  //Displays "bee." 
    C.bugFood();                   //Displays "nectar." 

[*] The only actual difference I can discern is that in example 3, 'constructor' is an enumerable attribute. When operator new is used 'constructor' becomes an attribute but is not enumerable. An attribute is enumerable if the for-in operation "for(var name in object)" returns the name of the attribute.

+34  A: 
pramodc84
Never knew about the first part. Nice!
mcjabberz
Similarly you can find out how many arguments a function is expecting with [`function.length`](https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference%3AGlobal_Objects%3AFunction%3Alength).
Xavi
@Xavi which is 1st part of the answer
pramodc84
Ahh, sorry I missed that...
Xavi
A: 

Well, it's not much of a feature, but it is very useful:

Shows selectable and formatted alerts:

alert(prompt('',something.innerHTML ));
vsync
+2  A: 

These are not always a good idea, but you can convert most things with terse expressions. The important point here is that not every value in JavaScript is an object, so these expressions will succeed where member access on non-objects like null and undefined will fail. Particularly, beware that typeof null == "object", but you can't null.toString(), or ("name" in null).

Convert anything to a Number:

+anything
Number(anything)

Convert anything to an unsigned four-byte integer:

anything >>> 0

Convert anything to a String:

'' + anything
String(anything)

Convert anything to a Boolean:

!!anything
Boolean(anything)

Also, using the type name without "new" behaves differently for String, Number, and Boolean, returning a primitive number, string, or boolean value, but with "new" these will returned "boxed" object types, which are nearly useless.

Kris Kowal
+8  A: 

My favorite trick is using apply to perform a callback to an object's method and maintain the correct "this" variable.

function MakeCallback(obj, method) {
    return function() {
        method.apply(obj, arguments);
    };
}

var SomeClass = function() { 
     this.a = 1;
};
SomeClass.prototype.addXToA = function(x) {
     this.a = this.a + x;
};

var myObj = new SomeClass();

brokenCallback = myObj.addXToA;
brokenCallback(1); // Won't work, wrong "this" variable
alert(myObj.a); // 1


var myCallback = MakeCallback(myObj, myObj.addXToA);
myCallback(1);  // Works as expected because of apply
alert(myObj.a); // 2
Seth
A: 

If I call a javascript function in html body like below:

<html>
<head>
  <title>Test Page</title>

</head>

<body>
<form action="h.html" name="a" method="post">
<input type="hidden" name="name"/>
<input type="hidden" name="name2"/>
<input type="hidden" name="name3"/>

<script language="javascript">
a.submit();
</script>
</form>

</body>
</html>

It will not submit the form always. But if I write some text or   before the script as below.

Please wait....
 <script language="javascript">
    a.submit();
    </script>

Then the script will execute always.

Himadri
This is a load a crap.
ken
be nice to be able to delete it... 8o
NixNinja
+2  A: 

Hm, I didn't read the whole topic though it's quite interesting for me, but let me make a little donation:

// forget the debug alerts
var alertToFirebugConsole = function() {
 if ( window.console && window.console.log ) {
  window.alert = console.log;
 }
}
Lyubomyr Shaydariv
A: 

function can have methods.

I use this pattern of AJAX form submissions.

var fn = (function() {
  var ready = true;
  function fnX() {
   ready = false;
   // AJAX return function
   function Success() {
    ready = true;
   }
   Success();
   return "this is a test";
  }

  fnX.IsReady = function() {
   return ready;
  }
  return fnX;
 })();

 if (fn.IsReady()) {
  fn();
 }
Kenneth J
This pattern is not hidden at all :)
Lyubomyr Shaydariv
A: 

I think, setTimeout function should be the best hidden feature of JavaScript. First time when I studied JavaScript, every books or every website always tell about how to use “setTimeout” function like “eval” function but it has delay time before execute. Please look at the following code.

// This code will shows 'Hello World!' message in modal dialog after 1 s.
setTimeout("alert('Hello World!');", 1000);

I just know that we can call this function by passing function as the first parameter like the following code.

// This code will works like the above function.
setTimeout(function()
{
    alert('Hello World!');
}, 1000);

As you know, the first code style has benefit about dynamic creating statement. But it can't receive any private variable in current scope like the following code.

var x = 3;
var statement = 'x';

// Set statement to 'x + x + x + x + x'
for(var i = 0; i < 4;i++)
{
    statement += " + x";
}

// Display result of 'x + x + x + x + x' that is 15 after 1 s.
// However, this code will throw exception because it cannot find 'x' variable in global scope.
setTimeout('alert(' + statement + ')', 1000);

By the way, you can solve this error by using my second pattern that I just tell like the following code.

var x = 3;
setTimeout(function()
{
    var result = 0;

    for(var i = 0; i < 5;i++)
    {
        result += x;
    }

    // Show result of the above calculation that is 15 without error.
    alert(result);
}, 1000);

I think that 99% of web developers (excluding JavaScript plug-in developer) do not know about this pattern.

Soul_Master
I recently had a talk when I was explaining my friend how does setTimeout() works indeed. The problem in setTimeout() for many people when they begin to learn JavaScript is just unknowing that an expression given to setTimeout() must be a code anyway. If only a function for setTimeout() is given, then setTimeout() calls the function when the time is elapsed. I prefer to pass the function objects to use closures. We can also simulate pre-timeout and post-timeout behavior using something like this: setTimeout(function(){alert("pre timeout");return function () {alert("postTimeout");};}(),1000);
Lyubomyr Shaydariv
setTimeout is not part of the language, it is something the browser as a host exposes.
galambalazs
A: 

While not exactly a hidden feature, you don't need to use typeof to check for undefinedness. I only mention this because I see the typeof versions way too often for my liking.

Instead of

typeof foo == "undefined"

or

typeof foo === "undefined"

you probably want to do

foo === undefined

Note: The triple '=' characters are needed in the above example!

Analogous statements for != / !== apply as well.

trinithis
Just to notice why most people use `typeof`: The `typeof` way is *safer*, because the `undefined` global property is provided by the browser (this property contains the primitive value `undefined`), and while all modern browsers provide it is certainly not *guaranteed* to work by spec, as the `typeof` way is, also, this property is not ReadOnly, and can be overriden or shadowed in the scope chain.
CMS
Learn something new every day :DThough my opinion still stands. Otherwise we would all be fretting about whether Object refers to the real Object and silly stuff like that. Just because certain things can be done doesn't mean they should. Dynamic languages require discipline.
trinithis
Does not work (at least in Firefox) an error will be thrown: `ReferenceError:foo is not defined`. This is because you attempt to use the undefined variable foo in order to check it against undefined. If it's a global variable you can do: `window.foo === undefined`.
slebetman
Well you shouldn't even reference variables that you don't even define (at least somewhere in the same scope).
trinithis
You can do this in javascript: *undefined = true; foo === undefined; //false* undefined is just another variable, which happens to be undefined at first.
Pim Jager
So what? You can also do: `Array.prototype = Number.prototype = String.prototype = Object.prototype = 0`, but I don't see people complaining that you shouldn't use these variables because you "don't know what they are (really)". Such a BS argument.
trinithis
+1  A: 

JavaScript is considered to be very good at exposing all its object so no matter if its window object itself.

So if i would like to override the browser alert with JQuery/YUI div popup which too accepts string as parameter it can be done simply using following snippet.


function divPopup(str)
{
    //code to show the divPopup
}
window.alert = divPopup;

With this change all the calls to the alert() will show the good new div based popup instead of the browser specific alert.

Anil Namde
+8  A: 

The Zen of Closures

Other people have mentioned closures. But it's surprising how many people know about closures, write code using closures, yet still have the wrong perception of what closures really are. Some people confuse first-class functions with closures. Yet others see it as a kind of static variable.

To me a closure is a kind of 'private' global variable. That is, a kind of variable that some functions see as global but other functions can't see. Now, I know this is playing fast and loose with the description of the underlying mechanism but that is how it feels like and behaves. To illustrate:

// Say you want three functions to share a single variable:

// Use a self-calling function to create scope:
(function(){

    var counter = 0; // this is the variable we want to share;

    // Declare global functions using function expressions:
    increment = function(){
        return ++counter;
    }
    decrement = function(){
        return --counter;
    }
    value = function(){
        return counter;
    }
})()

now the three function increment, decrement and value share the variable counter without counter being an actual global variable. This is the true nature of closures:

increment();
increment();
decrement();
alert(value()); // will output 1

The above is not a really useful use of closures. In fact, I'd say that using it this way is an anti-pattern. But it is useful in understanding the nature of closures. For example, most people get caught when they try to do something like the following:

for (var i=1;i<=10;i++) {
    document.getElementById('span'+i).onclick = function () {
        alert('this is span number '+i);
    }
}
// ALL spans will generate alert: this span is span number 10

That's because they don't understand the nature of closures. They think that they are passing the value of i into the functions when in fact the functions are sharing a single variable i. Like I said before, a special kind of global variable.

To get around this you need detach* the closure:

function makeClickHandler (j) {
    return function () {alert('this is span number '+j)};
}

for (var i=1;i<=10;i++) {
    document.getElementById('span'+i).onclick = makeClickHandler(i);
}
// this works because i is passed by reference 
// (or value in this case, since it is a number)
// instead of being captured by a closure

*note: I don't know the correct terminology here.

slebetman
This is a very useful post, thanks. Just a minor nitpick. In the for loop, it should be i=1, not i=i. Also, I couldn't get the workaround to work. Maybe you meant this instead: function makeClickHandler(j) {return function() { alert('this is span number ' + j); }; }
Steve
@Steve: Thanks for spotting the bugs.
slebetman
+17  A: 

I know I'm late to the party, but I just can't believe the + operator's usefulness hasn't been mentioned beyond "convert anything to a number". Maybe that's how well hidden a feature it is?

// Quick hex to dec conversion:
+"0xFF";              // -> 255

// Get a timestamp for now, the equivalent of `new Date().getTime()`:
+new Date();

// Safer parsing than parseFloat()/parseInt()
parseInt("1,000");    // -> 1, not 1000
+"1,000";             // -> NaN, much better for testing user input
parseInt("010");      // -> 8, because of the octal literal prefix
+"010";               // -> 10, `Number()` doesn't parse octal literals 

// A use case for this would be rare, but still useful in cases
// for shortening something like if (someVar === null) someVar = 0;
+null;                // -> 0;

// Boolean to integer
+true;                // -> 1;
+false;               // -> 0;

// Other useful tidbits:
+"1e10";              // -> 10000000000
+"1e-4";              // -> 0.0001
+"-12";               // -> -12

Of course, you can do all this using Number() instead, but the + operator is so much prettier!

You can also define a numeric return value for an object by overriding the prototype's valueOf() method. Any number conversion performed on that object will not result in NaN, but the return value of the valueOf() method:

var rnd = {
    "valueOf": function () { return Math.floor(Math.random()*1000); }
};
+rnd;               // -> 442;
+rnd;               // -> 727;
+rnd;               // -> 718;
Andy E
+1  A: 

JavaScript versatility - Overriding default functionality


Here's the code for overriding the window.alert function with jQuery UI's Dialog widget. I did this as a jQuery plug-in. And you can read about it on my blog; altAlert, a jQuery plug-in for personalized alert messages.

jQuery.altAlert = function (options)  
{  
    var defaults = {  
        title: "Alert",  
        buttons: {  
            "Ok": function()  
            {  
                jQuery(this).dialog("close");  
            }  
        }  
    };  

    jQuery.extend(defaults, options);  

    delete defaults.autoOpen;  

    window.alert = function ()  
    {  
        jQuery("<div />", {
            html: arguments[0].replace(/\n/, "<br />")
        }).dialog(defaults);  
    };  
};
roosteronacid
Almost never a good idea... but certainly good to know. I only use it to fix `parseInt` horrible default behavior (octal base by default). So to have decimal be default: `___parseInt = parseInt; parseInt = function (str, base) { return ___parseInt(str, base || 10) };`
Infinity
A: 

Simple self-contained function return value caching:

function isRunningLocally(){
    var runningLocally = ....; // Might be an expensive check, check whatever needs to be checked.

    return (isRunningLocally = function(){
        return runningLocally;
    })();
},

The expensive part is only performed on the first call, and after that all the function does is return this value. Of course this is only useful for functions that will always return the same thing.

Infinity
+9  A: 

In a function, you can return the function itself:

function showSomething(a){
   alert(a);
   return arguments.callee;
}

// Alerts: 'a', 'b', 'c'
showSomething('a')('b')('c');

// Or what about this:
(function (a){
   alert(a);
   return arguments.callee;
}​)('a')('b')('c');​​​​

I don't know when it could be useful, anyway, it's pretty weird and fun:

var count = function(counter){
   alert(counter);
   if(counter < 10){
      return arguments.callee(counter+1);
   }
   return arguments.callee;
};

count(5)(9); // Will alert 5, 6, 7, 8, 9, 10 and 9, 10
Harmen
That's pretty cool.
Pim Jager
+1  A: 

Closures:

function f() { 
    var a; 
    function closureGet(){ return a; }
    function closureSet(val){ a=val;}
    return [closureGet,closureSet];
}

[closureGet,closureSet]=f(); 
closureSet(5);
alert(closureGet()); // gives 5

closureSet(15);
alert(closureGet()); // gives 15

The closure thing here is not the so-called destructuring assignment ([c,d] = [1,3] is equivalent to c=1; d=3;) but the fact that the occurences of a in closureGet and closureSet still refer to the same variable. Even after closureSet has assigned a a new value!

artistoex
+3  A: 

This is a hidden feature of jQuery, not Javascript, but since there will never be a "hidden features of jQuery" question...

You can define your own :something selectors in jQuery:

$.extend($.expr[':'], {
  foo: function(node, index, args, stack) {
    // decide if selectors matches node, return true or false
  }
});

For selections using :foo, such as $('div.block:foo("bar,baz") span'), the function foo will be called for all nodes which match the already processed part of the selector. The meaning of the arguments:

  • node holds the current node
  • index is the index of the node in the node set
  • args is an array that is useful if the selector has an argument or multiple names:
    • args[0] is the whole selector text (e.g. :foo("bar, baz"))
    • args[1] is the selector name (e.g. foo)
    • args[2] is the quote character used to wrap the argument (e.g. " for :foo("bar, baz")) or an empty string if there is no quoting (:foo(bar, baz)) or undefined if there is no argument
    • args[3] is the argument, including any quotes, (e.g. "bar, baz") or undefined if there are no arguments
  • stack is the node set (an array holding all nodes which are matched at that point)

The function should return true if the selector matches, false otherwise.

For example, the following code will enable selecting nodes based on a full-text regexp search:

$.extend($.expr[':'], {
  matches: function(node, index, args, stack) {
    if (!args.re) { // args is a good place for caching
      var re = args[3];
      if (args[2]) { // get rid of quotes
        re = re.slice(1,-1);
      }
      var separator = re[0];
      var pos = re.lastIndexOf(separator);
      var modifiers = re.substr(pos+1);
      var code = re.substr(1, pos-1);
      args.re = new RegExp(code, modifiers);
    }
    return $(node).text().match(args.re);
  }
});

// find the answers on this page which contain /**/-style comments
$('.answer .post-text code:matches(!/\\*[\\s\\S]*\\*/!)');

You could reach a similar effect with the callback version of .filter(), but custom selectors are much more flexible and usually more readable.

Tgr
Very nice write-up, I've done these before but the details always escape me. I might suggest stating which version(s) of jQuery this is valid for / tested with, though.
ken
@kenb: tested with 1.3.2 and 1.4.2. The contents of `args` are different on 1.2.6.
Tgr
*"since there will never be a "hidden features of jQuery" question..."* - believe me there will be...
galambalazs
Hidden (or not widely known) features of jQuery: http://stackoverflow.com/questions/121965/hidden-or-not-widely-known-features-of-jquery
Ates Goral
+1  A: 

When you are write callbacks you have a lot of code, which will look like this:

callback: function(){
  stuff(arg1,arg2);
}

You can use the function below, to make it somewhat cleaner.

callback: _(stuff, arg1, arg2) 

It uses a less well known function of the Function object of javascript, apply.

It also shows another character you can use as functionname: _.

function _(){
        var func;
        var args = new Array();
        for(var i = 0; i < arguments.length; i++){
                if( i == 0){
                        func = arguments[i];
                } else {
                        args.push(arguments[i]);
                }
        }
        return function(){
                return func.apply(func, args);
        }
}
Edgar Klerks
There are similar implementations around, most notably the `Function.prototype.bind()` method in ECMAScript 5th Edition and the PrototypeJS library. With that, you could do `stuff.bind(null, arg1, arg2);`. See [bobince's answer here](http://stackoverflow.com/questions/2568966/how-do-i-pass-the-value-not-the-reference-of-a-js-variable-to-a-function/2569493#2569493).
Andy E
What's `xfunction`? A typo?
Marcel Korpel
I think so. Fixed.
Delan Azabani
This is really function currying, so I would call the function `curry` instead of `_`. Also ideally curry should be a method of `Function.prototype`
Infinity
Doesn't support use from an object context. Change the first parameter to apply to `this`. And how about just: `function _() { var args = Array.prototype.slice.call(arguments); return function() { args.shift().apply(this,args); }; }`
nicerobot
@nicerobot Tnx, that is a nicer [email protected] It is not currying. At least in haskell it means changing the type of a <code>function (a,b) -> c to a -> b -> c</code><br/>See for more information:http://www.haskell.org/haskellwiki/Currying With currying you can do stuff like: <code>func(1,2,3) == func(1)(2,3) == func(1)(2)(3).</code> There are a lot of implementations of currying in javascript. <br/>It is indeed like bind.
Edgar Klerks
It's a less readable form of partial application.
galambalazs