Best javascript questions in January 2012

Can anyone explain these bizarre Javascript behaviours mentioned in the 'Wat' talk for CodeMash 2012?

235 votes

The talk is here: https://www.destroyallsoftware.com/talks/wat

It basically points out a few bizarre quirks with Ruby and Javascript.

I have made a JSFiddle of the results here: http://jsfiddle.net/fe479/1/

The behaviours specific to Javascript (As I don't know Ruby) are listed below.

I found in the JSFiddle that some of my results didn't correspond with those in the video, I am not sure why. I am however curious to know how Javascript is handling working behind the scenes in each case.

Empty Array + Empty Array
[] + []
result:
<Empty String>

I am quite curious about the + operator when used with arrays in Javascript. This matches the video's result.

Empty Array + Object
[] + {}
result:
[Object]

This matches the video's result. What's going on here? Why is this an object. What does the + operator do?

Object + Empty Array
{} + []
result
[Object]

This doesn't match the video. The video suggests that the result is 0, whereas I get [Object].

Object + Object
{} + {}
result:
[Object][Object]

This doesn't match the video either, nor can I understand how outputting a variable can result in two objects. Any ideas? Maybe my JSFiddle is wrong.

Array(16).join("wat" - 1)
result:
NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

doing wat + 1 results in wat1wat1wat1wat1...

I suspect this is just straightforward behaviour that trying to subtract a number from a string results in NaN.

Any explanations?

Here's a list of explanations for the results you're seeing (and supposed to be seeing). The references I'm using are from the ECMA-262 standard.

  1. [] + []

    When using the addition operator, both the left and right operands are converted to primitives first (§11.6.1). As per §9.1, converting an object (in this case an array) to a primitive returns its default value, which for objects with a valid toString() method is the result of calling object.toString() (§8.12.8). For arrays this is the same as calling array.join() (§15.4.4.2). Joining an empty array results in an empty string, so step #7 of the addition operator returns the concatenation of two empty strings, which is the empty string.

  2. [] + {}

    Similar to [] + [], both operands are converted to primitives first. For "Object objects" (§15.2), this is again the result of calling object.toString(), which for non-null, non-undefined objects is "[object Object]" (§15.2.4.2).

  3. {} + []

    The {} here is not parsed as an object, but instead as an empty block (§12.1, at least as long as you're not forcing that statement to be an expression, but more about that later). The return value of empty blocks is empty, so the result of that statement is the same as +[]. The unary + operator (§11.4.6) returns ToNumber(ToPrimitive(operand)). As we already know, ToPrimitive([]) is the empty string, and according to §9.3.1, ToNumber("") is 0.

  4. {} + {}

    Similar to the previous case, the first {} is parsed as a block with empty return value. Again, +{} is the same as ToNumber(ToPrimitive({})), and ToPrimitive({}) is "[object Object]" (see [] + {}). So to get the result of +{}, we have to apply ToNumber on the string "[object Object]". When following the steps from §9.3.1, we get NaN as a result:

    If the grammar cannot interpret the String as an expansion of StringNumericLiteral, then the result of ToNumber is NaN.

  5. Array(16).join("wat" - 1)

    As per §15.4.1.1 and §15.4.2.2, Array(16) creates a new array with length 16. To get the value of the argument to join, §11.6.2 steps #5 and #6 show that we have to convert both operands to a number using ToNumber. ToNumber(1) is simply 1 (§9.3), whereas ToNumber("wat") again is NaN as per §9.3.1. Following step 7 of §11.6.2, §11.6.3 dictates that

    If either operand is NaN, the result is NaN.

    So the argument to Array(16).join is NaN. Following §15.4.4.5 (Array.prototype.join), we have to call ToString on the argument, which is "NaN" (§9.8.1):

    If m is NaN, return the String "NaN".

    Following step 10 of §15.4.4.5, we get 15 repetitions of the concatenation of "NaN" and the empty string, which equals the result you're seeing. When using "wat" + 1 instead of "wat" - 1 as argument, the addition operator converts 1 to a string instead of converting "wat" to a number, so it effectively calls Array(16).join("wat1").

As to why you're seeing different results for the {} + [] case: When using it as a function argument, you're forcing the statement to be an ExpressionStatement, which makes it impossible to parse {} as empty block, so it's instead parsed as an empty object literal.

Why does (x += x += 1) evaluate differently in C and Javascript?

32 votes

If the value of the variable x is initially 0, the expression x += x += 1 will evaluate to 2 in C, and to 1 in Javascript.

The semantics for C seems obvious to me: x += x += 1 is interpreted as x += (x += 1) which is, in turn, equivalent to

x += 1
x += x  // where x is 1 at this point

What is the logic behind Javascript's interpretation? What specification enforces such behaviour? (It should be noted, by the way, that Java agrees with Javascript here).

Update: It turns out the expression x += x += 1 has undefined behaviour according to the C standard (thanks ouah, John Bode, DarkDust, Drew Dormann), which seems to spoil the whole point of the question for some readers. The expression can be made standards-compliant by inserting an identity function into it as follows: x += id(x += 1). The same modification can be made to the Javascript code and the question still remains as stated. Presuming that the majority of the readers can understand the point behind "non-standards-compliant" formulation I'll keep it as it is more concise.

Update 2: It turns out that according to C99 the introduction of the identity function is probably not solving the ambiguity. In this case, dear reader, please regard the original question as pertaining to C++ rather than C99, where "+=" can be most probably now safely be regarded as an overloadable operator with a uniquely defined sequence of operations. That is, x += x += 1 is now equivalent to operator+=(x, operator+=(x, 1)). Sorry for the long road to standards-compliance.

JavaScript and Java have pretty much strict left-to-right evaluation rules for this expression. C does not (even in the version you provided that has the identity function intervening).

The ECMAscript spec I have (3rd Edition, which I'll admit is quite old - the current version can be found here: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf) says that compound assignment operators are evaluated like so:

11.13.2 Compound Assignment ( op= )

The production AssignmentExpression : LeftHandSideExpression @ = AssignmentExpression, where@ represents one of the operators indicated above, is evaluated as follows:

  1. Evaluate LeftHandSideExpression.
  2. Call GetValue(Result(1)).
  3. Evaluate AssignmentExpression.
  4. Call GetValue(Result(3)).
  5. Apply operator @ to Result(2) and Result(4).
  6. Call PutValue(Result(1), Result(5)).
  7. Return Result(5)

You note that Java has the same behavior as JavaScript - I think it's spec is more readable, so I'll post some snippets here (http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.7):

15.7 Evaluation Order

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

It is recommended that code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect, as its outermost operation, and when code does not depend on exactly which exception arises as a consequence of the left-to-right evaluation of expressions.

15.7.1 Evaluate Left-Hand Operand First The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated. For example, if the left-hand operand contains an assignment to a variable and the right-hand operand contains a reference to that same variable, then the value produced by the reference will reflect the fact that the assignment occurred first.

...

If the operator is a compound-assignment operator (§15.26.2), then evaluation of the left-hand operand includes both remembering the variable that the left-hand operand denotes and fetching and saving that variable's value for use in the implied combining operation.

On the other hand, in the not-undefined-behavior example where you provide an intermediate identity function:

x += id(x += 1);

while it's not undefined behavior (since the function call provides a sequence point), it's still unspecified behavior whether the leftmost x is evaluated before the function call or after. So, while it's not 'anything goes' undefined behavior, the C compiler is still permitted to evaluate both x variables before calling the id() function, in which case the final value stored to the variable will be 1:

For example, if x == 0 to start, the evaluation could look like:

tmp = x;    // tmp == 0
x = tmp  +  id( x = tmp + 1)
// x == 1 at this point

or it could evaluate it like so:

tmp = id( x = x + 1);   // tmp == 1, x == 1
x = x + tmp;
// x == 2 at this point

Note that unspecified behavior is subtly different than undefined behavior, but it's still not desirable behavior.

In Javascript: Why new Date('2012-1-15') - new Date('2012-01-15') == 21600000

30 votes

I'm confused but in javascript:

> new Date('2012-1-15') - new Date('2012-01-15')
  21600000

Why is that? (21600000 / 1000 / 3600 == 6 hours)

The date format yyyy-mm-dd (2012-01-15) is parsed as being a UTC date while yyyy-m-dd (2012-1-15) is parsed as a local date. This is shown if you use .toString on each.

> (new Date( '2012-01-15' )).toString()
"Sat Jan 14 2012 16:00:00 GMT-0800 (Pacific Standard Time)"
> (new Date( '2012-1-15' )).toString()
"Sun Jan 15 2012 00:00:00 GMT-0800 (Pacific Standard Time)"

Note that I am in California, hence the Pacific Standard Time. If you are in a different time zone you will get different results.

When JavaScript parses dates it tries formats used in more areas (such as UTC) first before it tries localized date formats. The last part of the UTC date format is a timezone offset from GMT which is assumed to be 0 when it is missing (as it is in this example). To get the same date you would need the full UTC timestamp: 2012-01-15T00:00:00-08:00.

Is it a good idea to use a switch with fallthrough to handle default arguments in Javascript?

26 votes

I have recently learned that you can use a switch statement with fallthrough to set default arguments in Javascript:

function myFunc(arg1, arg2, arg3) {
    switch (arguments.length) {
        case 0 : arg1 = "default1";
        case 1 : arg2 = "default2";
        case 2 : arg3 = "default3";
    }
}

The traditional way that I usually see involves testing the truthyness of that parameters (since unpassed parameters evaluate to undefined)

function myFunc(arg1, arg2, arg3){
    arg1 = arg1 || "default1";
    arg2 = arg2 || "default2";
    arg3 = arg3 || "default3";
}

My inital though after seeing the version using the switch was that I should consider using it "by default" over the || version.

The switch fallthough makes it not much longer and it has the advantage that it is much more "robust" in that it does not care about the types of the parameters. In the general case, it sounds like a good idea to not have to worry about what would happen with all the falsy values ('', 0, null, false ...) whenever I have to make a function with default parameters.

I would then reserve the arg = arg || x for the actual cases where I want to check for truthyness instead of repurposing it as the general rule for parameter defaulting.

However, I found very few examples of this pattern when I did a code search for it so I had to put on my skeptic hat. Why didn't I find more examples of this idiom?

  • Is it just now very well known?
  • Did I not search well enough? Did I get confused by the large number of false positives?
  • Is there something that makes it inferior to the alternatives?

Some reasons that I (and some of the comments) could think of for avoiding switch(arguments.length):

  • Using named parameters passed via an object literal is very flexible and extensible. Perhaps places where more arguments can be optional are using this instead?

  • Perhaps most of the time we do want to check for truthyness? Using a category of values as palceholders also allows default parameters to appear in the middle instead of only at the end : myFunc('arg1', null, 'arg3')

  • Perhaps most people just prefer the very short arg = arg || "default" and most of the time we just don't care about falsy values?

  • Perhaps switch case fallthrough is always evil/unmantainable and those who know about the switch(arguments.length) idiom have learned to avoid it?

  • Perhaps accessing arguements is evil/unperformant/deprecated ?

Are these cons enough to avoid using switch(arguments.length) as a staple default argument pattern or is it a neat trick I should keep and use in my code?

Since the question has been updated, it's really a matter of opinion. There are a number of javascript features that many people suggest avoiding, such as switch and ternary. This is why there is not a lot of information on some of those features.

The reason that suggestion is made is because many people miss-use those features and create problems in their code. The bugs are sometimes difficult to detect and it can be difficult for others to understand what your code is doing (particularly those unfamiliar with javascript or new programmers).

So if you like to do it that way, and you're not worried about the opinions (or skill level) of anyone working on your code. By all means, your approach will work. I have used the switch statement myself on occasion, and while I don't think it's really "good" or "bad", it's hard to find a situation that requires it.

You asked how I might go about this without an if-else chain:

function myFunc(args) {
    var allArgs = {
        arg1:"default1",
        arg2:"default2",
        arg3:"default3"
    };
    for (var key in args) {
        allArgs[key] = args[key];        
    }
}
myFunc({arg1:null, arg3:'test'})

Is it possible to emulate non-enumerable properties?

23 votes

ES5 has a enumerable flag. Example

Example

var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
 , pd = getOwnPropertyDescriptor(Object.prototype, "toString");

assert(pd.enumerable === false, "enumerability has the wrong value");

Partial implementation

Partial implementation is do-able by having Object.keys and Object.getOwnPropertyNames filter out new non-enumerable properties using the shimmed Object.defineProperty.

Introduction

This allows for properties to be non enumerable. This clearly means that Example

for (var key in {}) {
    assert(key !== "toString", "I should never print");
}

This allows us to add properties to say Object.prototype (Example)

Object.defineProperty(Object.prototype, "toUpperCaseString", {
    value: function toUpperCaseString() {
        return this.toString().toUpperCase();
    },
    enumerable: false
});

for (var key in {}) {
    assert(key !== "toUpperCaseString", "I should never print");
}

console.log(({}).toUpperCaseString()); // "[OBJECT OBJECT]"

Question

How can we emulate this in non-ES5 compliant browsers?

Browser compat table

In this case we care about potentially solving this for

  • IE < 9 (IE8 only works on DOM objects)
  • Firefox 3.6
  • Safari 4
  • Opera 11.5 (Opera 11.6 solves this).

The ES5-shim does not have a solution for this.

The ES5 shim has a solution for most ES5 features that will break your code if it doesn't work.

Is there any black magic that can be done with propiotory IE only APIs? Maybe with VBScript?

You can do it via code-rewriting. Rewrite every use of for (p in o) body to

for (p in o) {
  if (!o['__notenum_' + p]) body 
}

and then you can mark properties not enumerable by defining a __notenum_... property. To be compatible you would have to tweak the above to make sure that __notenum_propname is defined at the same prototype level as propname, and if you use them, overwrite eval and new Function to rewrite.

That's basically what ES5/3 does.

Is there any point of using "return !0" in javascript?

18 votes

If you go to a google result page, and run rwt.toString(), you'll see that the return call for this function is:

return !0;

I can't think of any reason why this wouldn't always be true. Is this just a shorthand for true, or is there more going on here?

It is always true, but it takes 2 bytes to download (!0 is 2 characters) instead of 4 bytes to download the boolean value true.

Most Javascript minifiers will convert true to !0 and false to !1. You can see an example of this by typing var y = true; with Simple optimizations on Google's Closure Compiler: http://closure-compiler.appspot.com/home

What is the purpose of the delete operator in Javascript?

17 votes

The behaviour of the delete operator seems very complicated and there are many misunderstandings about what it actually does. To me, it seems that reassigning something to undefined will more reliably do what you would expect.

I've never seen the delete keyword in Javascript actually used in non-example code and I am wondering if it is particularly useful for anything. Does delete have any purpose that cannot be acheived by reassignment to undefined? Is it used at all in any of the famous libraries (e.g. jQuery, dojo, backbone, etc)?

Does delete have any purpose that cannot be acheived by reassignment to undefined?

Yes. If you want to unmask a property from a prototype or cause in, hasOwnProperty, and for (...in...) to not record the property as existing then delete is appropriate.

var set = {};

set._x = true;

alert('_x' in set);  // true

set._x = undefined;

alert('_x' in set);  // true

delete set._x;

alert('_x' in set);  // false

EDIT: As T.J. Crowder explains:

The purpose of the delete operator is to completely remove a property from an object, whereas setting a property to undefined just sets the property to undefined.

This matters in its own right, but it also matters when you're using inheritance, because if O derives from P

var P = { prop: 42 };
var O = Object.create(P);  // P is O's prototype.

when you retrieve O.prop, you get the value of prop from O if O has a property with that name (even if its value is undefined), but if O doesn't have the property at all, then the value will be retrieved from P.prop instead.

alert(O.prop);  // "42" since O doesn't have its own prop, but P does.
O.prop = undefined;
alert(O.prop);  // "undefined" since O has its own prop.
delete O.prop;
alert(O.prop);  // "42" since the delete "unmasked" P.prop.

How do these javascript obfuscators generate actual working code?

16 votes

There's this one and this one and they both generate completely unreadable code, one being more adorable than the other.

Now, I'm no expert in Javascript, but I fail to see how

゚ω゚ノ= /`m´)ノ ~┻━┻   //*´∇`*/ ['_']; o=(゚ー゚)  =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (c^_^o)+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) - (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (゚Θ゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (o^_^o)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚Θ゚)+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((゚ー゚) + (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ (゚ー゚)+ ((o^_^o) +(o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ (゚ー゚)+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((゚ー゚) + (゚Θ゚))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚Θ゚)+ ((o^_^o) +(o^_^o))+ ((゚ー゚) + (o^_^o))+ (゚Д゚)[゚ε゚]+(゚ー゚)+ ((o^_^o) - (゚Θ゚))+ (゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+ (゚Θ゚)+ (゚Д゚)[゚o゚]) (゚Θ゚)) ('_');

and

$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.__+"(\\\"\\"+$.__$+$._$_+$._$$+$.__+$.$_$_+$.$$__+"\\"+$.__$+$.$_$+$._$$+"\\"+$.__$+$.__$+$.$$$+"\\"+$.__$+$.$$_+$.$$_+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.$$$$+(![]+"")[$._$_]+$._$+"\\"+$.__$+$.$$_+$.$$$+"\\\")"+"\"")())();

are actual valid javascript that do as expected. Seriously, run them. They're both alert("StackOverflow"). I could understand obfuscating some logic or string obfuscation, but there's no visible control statements. Is this obfuscator pulling some magic in the style of The Language Which Shall Not Be Named? I'm happy with my code looking happy too, but I'm completely not understanding the magic behind it.

I've tried picking through the sourcecode of both pages, and they're as confusing for me as the code they generate.

How does this work?

As my javascript excerise of the day, a line by line break down. Note I generated mine with alert("Hello")

$ = ~[];   // var $ = -1
$ = 
    {
    ___ : ++$,              // ++(-1) == 0
    $$$$:(![]+"")[$],       // ![] == false, false + "" == "false", "false"[0] == "f"
    __$:++$,                // ++(0) == 1    
    $_$_:(![]+"")[$],       // ![] == false, false + "" == "false", "false"[1] == "a"
    _$_:++$,                // ++(1) == 2
    $_$$:({}+"")[$],        // {} + "" == "[object Object]", "[object Object]"[2] == "b"
    $$_$:($[$]+"")[$],      // 2[2] == undefined + "" == "undefined", "undefined"[2] == "d"
    _$$:++$,                // ++(2) == 3
    $$$_:(!""+"")[$],       // !"" == true + "" == "true", "true"[3] == "e"
    $__:++$,                // ++(3) == 4
    $_$:++$,                // ++(4) == 5
    $$__:({}+"")[$],        // ({} + "") == [object Object]", "[object Object]"[5] == "c"
    $$_:++$,                // ++(5) == 6
    $$$:++$,                // ++(6) == 7
    $___:++$,               // ++(7) == 8
    $__$:++$                // ++(8) == 9
};

$.$_ = 
    ($.$_=$+"")[$.$_$] +        // "[object Object]"[5] == "c" +  (also $.$_ = "[object Object]")
    ($._$=$.$_[$.__$]) +        // "[object Object]"[1] == "o" + (also $._$ = "o")
    ($.$$=($.$+"")[$.__$]) +    // $.$+"" == "undefined", "undefined"[1] == "n" + (also $.$$ = "n")
    ((!$)+"")[$._$$] +          // !$ == false, false+"" == "false", "false"[3] == "s" +
    ($.__=$.$_[$.$$_]) +        // "[object Object]"[6] == "t" (also $.__ = "t") +
    ($.$=(!""+"")[$.__$]) +     // !"" == true, true + "" == "true", "true"[2] == "r" +(also $.$="r")
    ($._=(!""+"")[$._$_]) +     // !"" == true, true + "" == "true", "true"[3] == "u" +(also $._="u")
    $.$_[$.$_$] +               // "[object Object]"[5] == "c" +
    $.__ +                      // "t" +
    $._$ +                      // "o" +
    $.$;                        // "r"

// $.$_ = "constructor"

$.$$ = 
    $.$ +                       // "r" +
    (!""+"")[$._$$] +           // "true"[3] == "e" +
    $.__ +                      // "t" +
    $._  +                      // "u" +
    $.$ +                       // "r" +
    $.$$;                       // "n" 
// $.$$ = "return"

$.$ = ($.___)[$.$_][$.$_];      // (0)["constructor"]["constructor"]
// $.$ = Function

// This is the part that changes when you change the input string.

$.$(                            // Function( 
    $.$(                        // Function (
        $.$$ +                  // "return"+
        "\""+                   // '"' +
        $.$_$_ +                // "a" + 
        (![]+"")[$._$_]+        // "l" + 
        $.$$$_+                 // "e" + 
        "\\"+                   // "\" +            
        $.__$+                  // "1" + 
        $.$$_+                  // "6" + 
        $._$_+                  // "2" +   (note '\162' = 'r')   
        $.__+                   // "t" + 
        "(\\\"\\"+              // '(\"\' +    
        $.__$+                  // 1 + 
        $.__$+                  // 1 + 
        $.___+                  // 0 +     (note '\110' = 'H')    
        $.$$$_+                 // e + 
        (![]+"")[$._$_]+        // "false"[2] == "l", "l" + 
        (![]+"")[$._$_]+        // "false"[2] == "l", "l" + 
        $._$+                   // "o" + 
        "\\\")"+                // '\")' +
        "\""                    // '"''
    )()                         // invoke
)();                            // invoke

am not i am is pretty much spot on, it creates a string and then invokes it.

Edit – and I don't have time to decode the other version, but I imagine its doing something similar, but with non latin characters.

If Javascript has first-class functions, why doesn't this work?

13 votes

Javascript is purported to have first-class functions, so this seems like the following ought to work:

var f = document.getElementById;
var x = f('x');

But it fails on all browsers, with a different cryptic error message on each one. Safari says "Type error". Chrome says "Illegal invocation". Firefox says "Could not convert Javascript argument."

Why?

Because in JavaScript functions arent bound to context (this). You may use bind():

var f = document.getElementById.bind(document);

13 votes

I am building a MVC 3 application where the users may not be in the same time zone, so my intent was to store everything in UTC and convert from UTC to local time in the views and localtime to UTC on submissions.

Doing some browsing though there doesn't seem to be a lot of good solutions to this. To be honest, I sort of expected an attribute to be available to auto convert UTC time into local time at least, but it seems not to exist.

I feel like just trying to be diligent about manually converting every input to UTC and manually converting every view to local time display will be very error prone and lead to difficult to detect bugs where the time is not converted to or from.

Any suggestions on how to deal with this as a general strategy?

EDIT Everyone seems very stuck on the "how do I get the client timezone" piece, which as I mention in one of the comments is not my concern. I am fine with a user setting that determines their timezone, so assume I already know what the client time zone is...that doesn't address my problem.

Right now, on each view when I render a date, I would need to call a method to render it in the local time zone from utc. Every time I send a date for submission to the server I need to convert it from the local timezone to UTC. If I forget to do this there will be problems...either a submitted date will be wrong or client side reports and filters will be wrong.

What I was hoping existed was a more automated method, especially since the view model is strongly typed in MVC 3 I was hoping for sum magic to be able to at least automatically render in a time zone, if not handle the submission, just like the date format or range can be controlled by an attribute.

So like

[DateRange]
Public DateTime MyDate

I could have something like

[ConvertToUTC(offset)]
Public DateTime MyDate

Anyway, I guess it look like my only approach would be to write a custom data annotation to render it in a time zone, and a override on the MVC 3 model binder so incoming dates are converted unless I want to wrap ever date in a method call. So unless anyone has further comments or suggestions it will be one of those two options, I'm just surprised something doesn't exist already to do this.

If I do implement a solution I will be sure to post it.

Edit 2 Something like This http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx for MVC 3 views and view models is what I am looking for.

Final Edit I marked epignosisx answer as correct, but also have a few comments to add. I found something similar here: http://dalldorf.com/blog/2011/06/mvc3-timezones-1/ With an implementation of getting the timezone from the client by placing it in the cookie for people that want that in part 2 (link below since the link on the first part of the article to part 2 doesn't work) http://dalldorf.com/blog/2011/09/mvc3-timezones-2/

Its important to note with these approaches that you MUST you Editfor and Displayfor instead of things like TextForFor as only EditFor and DisplayFor make use of the metadata providers used to tell MVC how to display the property of that type on the model. If you access the model values directly in the view (@Model.MyDate) no conversion will take place.

You could handle the problem of converting UTC to user local time by using website-wide DisplayTemplate for DateTime.

From your Views you would use @Html.DisplayFor(n => n.MyDateTimeProperty)

The second problem is tougher to tackle. To convert from user local time to UTC you could override the DefaultModelBinder. Specifically the method SetProperty. Here is a naive implementation that demonstrates the point. It only applies for DateTime but could easily be extended to DateTime?. Then set it up as your Default binder in the Global.asax

public class MyDefaultModelBinder : DefaultModelBinder
{
    protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, object value)
    {
        //special case for DateTime
        if(propertyDescriptor.PropertyType == typeof(DateTime))
        {
            if (propertyDescriptor.IsReadOnly)
            {
                return;
            }

            try
            {
                if(value != null)
                {
                    DateTime dt = (DateTime)value;
                    propertyDescriptor.SetValue(bindingContext.Model, dt.ToUniversalTime());
                }
            }
            catch (Exception ex)
            {
                string modelStateKey = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name);
                bindingContext.ModelState.AddModelError(modelStateKey, ex);
            }
        }
        else
        {
            //handles all other types
            base.SetProperty(controllerContext, bindingContext, propertyDescriptor, value);
        }
    }
}

When to declare a new (anonymous)function in javascript?

12 votes

I'm a bit confused in how functions operate in javascript. I understand that they're all objects but how does that change how I would use them as arguments?

For instance, if I'm trying to use a callback function where the 2nd argument is evaluated after 1000ms...

$(this).fadeIn(1000,function(){alert('done fading in');});

Why can't I achieve the same effect with:

$(this).fadeIn(1000,alert('done fading in'));

If I do, it evaluates both at the same time. That is, (this) element fades in and the alert pops up at the same time.

When I'm calling alert(arg), aren't I creating a new object which gets passed into fadeIn()?

How exactly does this work?

In this

 $(this).fadeIn(1000,alert('done fading in'));

what does fadeIn() see as its second argument? It's the result of calling

 alert('done fading in')

we are making the call to alert() before calling fadeIn().

In this case

$(this).fadeIn(1000,function(){alert('done fading in');});

we have an object

 function(){alert('done fading in');}

which fadeIn() calls at the right time.

Selecting text behind another element with createEvent

12 votes

I have a scenario where I have some text, which should be user-selectable. The problem is, that there's an UI overlay on top of it, which prevents selecting text by default. The logical way to keep the overlay and still be able to select the text, would be to use synthetic events (use document.createEvent), but due to some reason, it doesn't work as expected.

The events seem to be delegated correctly and fire their handlers, but no text is selected. I have an example here, which is a rough simplification of the problem.

A few notes

  1. In FF if you start your selection outside of the overlay, you are still able to select the text you want, even if it's under the overlay
  2. When you have a normal selection in the uncovered area and you click on the overlay, it would be expected from the delegated mousedown event to remove the selection, but it doesn't happen

Am I missing an event that should also be delegated (I have mousedown, mousemove and mouseup)? Or is it some kind of a security measure by browsers to disable such behavior (refer to the note nr 2)? Any other suggestions on how to get the desired result? I know I should work around the current overlay solution altogether, but I'm already curious about the problem itself.

I have found two solutions for this problem:

  1. "pointer-events" css property. Requires IE 9.0+ though.
  2. Seems like guys from ExtJS solved it by event forwarding: demo, source, blog post

How can jQuery behave like an object and a function?

12 votes

jQuery or $ seems to be a function:

typeof $; // "function"

And it acts like one:

$('div').removeClass(); // $ constructs a new object with some methods like removeClass

But when I drop the function parentheses it behaves like an object:

$.each(/* parameters */); // $ is an object with some methods like each

I'd like to know how this is possible and how I can implement this behaviour to my own functions.

Functions are also objects, so $.each can be defined in a similar way as an Object.

JavaScript is a prototypical language. For jQuery, this means that every instance of $ inherits methods from jQuery.prototype.See Notes

A very rough demo, to achieve the similar behaviour:

(function() { // Closure to not leak local variables to the global scope
    function f(a, b) {
        //Do something
    }
    // Prototype. All properties of f.prototype are inherited by instances of f.
    // An instance of f can be obtained by:    new f, new f(), Object.create(f)
    f.prototype.removeClass = function(a) {
        return a;
    };
    function $(a, b) {     return new f(a, b);   } // <--- "new f" !
    $.each = function(a) { alert(a);             }
    window.$ = $; // Publish public methods
})();

//Tests (these do not represent jQuery methods):
$.each("Foo");                   //Alerts "Foo" (alert defined at $.each)
alert($().removeClass('Blabla'));//Alerts "Blabla"

Notes

jQuery's root method is defined as follows (only relevants parts are shown):

(function(win) {
    var jQuery = function (selector, context) {
        return new jQuery.fn.init(selector, context, rootjQuery);
    }
    //$.fn = jQuery.fn is a shorthand for defining "jQuery plugins".
    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function(){ .... sets default properties...}
        ....other methods, such as size, get, etc...
        .... other properties, such as selector, length, etc...
    }
    jQuery.fn.removeClass = ...
    ...lots of stuff, including definitions of removeClass, etc..


    win.$ = win.jQuery = jQuery; //Pulish method
})(window);

The advantage of the prototype method is that it's very easy to chain methods and properties. For example:

$("body").find("div:first").addClass("foo");

A method to implement this feature could be:

$.fn.find = function(selector) {
    ...
    return $(...);
}

Smooth scrolling of image tiles on large grid?

12 votes

Long time listener, first time caller here.

Ok, I apologize for the length of this post, but I want to be very clear on what I'm trying to do and what I've tried to hopefully guide your answers.

The Goal: I am trying to create a grid of tiles (images) 100 x 100 and I will display only part of the grid at a time because the images are 240 x 120. By clicking buttons (note: no need for mouse scrolling, zooming, etc.), the user will scroll around horizontally and vertically.

As an analogy, take a checkers board that is set up to play and you are looking down on it. It would be quite simple to display, requiring only a few base images and putting them on a grid. Now, consider that you only wanted to show the bottom 1/3 of the board. Then when a user clicks up, they move their view to the middle and another click takes them to the top 1/3 of the board. This is a simple example of what I'm trying to accomplish except on a much larger grid with a smaller view / move.

What I've tried:

  1. First I wrote the code in PHP to draw the full 100x100 grid and everything looked great
  2. Then I altered the code to actually write files for each square, saving them as X-Y.png
  3. I got sucked into a world of map tools and zoomify type tools
  4. I had some partial success writing my own solution

Map tools / Zoomify Fail:

After getting the full map and tiles, I tried to figure out how the heck to scroll part of this window only. A light bulb went off: "what about something like how google maps does things!" That's when trouble started and I got sucked down the rabbit hole a bit researching all these map tools that really got me nowhere because, quite simply, they seem to be made only for displaying geographic maps.

I did, however, get led to Zoomify at one point or another and I thought it could really be an option. The first problem was I couldn't seem to get it to take my own tiles without one shot of the full image, so I tried every screen capture program under the sun to try getting a full shot of my browser with the full grid to let zoomify make them. Let's just say, that didn't work, but i tried with reduced size. It sort of worked, but lost a lot of quality and I realized that zoomify doesn't even really accomplish what I need because 1. the scroll is not that smooth; and 2. these images will eventually contain some links connected with their X-Y coords, which means I need control over how much is scrolled each time the up, down, left, right arrows will be clicked.

My Not so failed attempt to do it myself

Ok, then I got back to the basics and I threw the grid in a DIV with overflow:hidden on the CSS. Great, now I had a window. I didn't want to load all of these images at once, though, so I drew only part of the grid in absolutely positioned DIVs with unique ID's (e.g. Tile_1_1). This was all looking great, but now I needed to make it appear that you are scrolling around the grid as you click the arrow buttons, so I threw it up to a javascript function for this. I had the javascript calculate the new X and new Y and swap the Image source of all the tiles since they are all named after their X/Y coordinates on the grid. Actually, this totally worked and now the map is scrolling. The problem is, it's a bit choppy to just change the image sources. There is no illusion that we are moving around this grid as much as the content is just instantly changing. and THIS my friends is where I need our help.

Where did I go wrong? Was I on the right track with this latest attempt? Do I need to totally rethink this or is there some simple fix for moving the tiles a little more elegantly than swapping the source?

Please keep in mind that I've gotten quite good with php, css, etc., but I never really invested much time in javascript, so you might need to do a little more explaining in that area.

P.S. this was the closest thing I could find on these boards, but it never really got to a clear answer: Tile scrolling / preloading (Google Maps style) of HTML layers with Ajax

Update: Solution Used

I liked both Cobby and pseudosavant's answers. Pseudosavant's solution was really right up my ally with letting CSS do most of the hard work, however I went with Cobby's solution. I thought it would give me a little more control and because I'm actually using a diamond grid, I could wrap my head around it better (not saying the other one wouldn't necessarily work also).

Here is what I did. I know the code is a little crude and needs some cleanup, but maybe it can help someone.

First I needed to find the relationship between my X and Y axis, so I drew myself a little diagram.

enter image description here

I quickly noticed that more X meant starting the diamond both farther left and higher to get the right coordinates in the center of the view (user defined start) and then offset by the Y coordinates to take off some of the negative left and lower the starting point.

Then, the PHP to draw the grid looks something like this ($xcoord and $ycoord come from a form):

//draw the grid
//Offset leftStart and topStart by Xcoord
$leftStart = 360 - ($xcoord * 120);
$topStart = 360 - ($xcoord * 60);

//Offset leftStart and topStart by Ycoord
$leftStart += ($ycoord * 120);
$topStart -= ($ycoord * 60);

for($y = 1; $y <= 99; $y++) { //y min to y max
    $left = $leftStart;
    $top = $topStart;
    for($x = 1; $x <= 99; $x++) { //x min to x max
       //I only want to draw part of the square
       if(($x < ($xcoord + 6)  && $x > ($xcoord - 6)) && ($y < ($ycoord + 6)  && $y > ($ycoord - 6))) {
          //Put out the image - this is how i needed mine formated
          echo "\t<div class=\"move\" id=\"T" . $x . "_" . $y . "\" style='position:absolute; left:" . $left . "px; top:" . $top . "px;'>\n";
          echo "\t\t<img src=\"./<path to your image>" . $x . "-" . $y . ".gif\">\n";
          echo "\t</div>\n";
       }
       $left = $left + 120;
       $top = $top + 60;
    }
$leftStart = $leftStart - 120;
$topStart = $topStart + 60;
}

Throw a DIV around that with overflow:hidden and give it an ID (mine is #tileView). OK, now you have a diamond grid drawn inside your view and now we need to start moving it!

This is how my jquery looks. Sorry if it needs improvement, I just learned Jquery and Ajax yesterday.

<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
    $("#top").click(function(){
        var y = document.getElementById('ycoord').value;
        var x = document.getElementById('xcoord').value;
        $(".move").animate({"left": "-=120px", "top": "+=60px"}, 500);
        changeImg(x, y, 'up');
        $("#ycoord").val(parseInt( y ) - 1);
    });     
    $("#bottom").click(function(){
        var y = document.getElementById('ycoord').value;
        var x = document.getElementById('xcoord').value;
        $(".move").animate({"left": "+=120px", "top": "-=60px"}, 500);
        changeImg(x, y, 'down');
        $("#ycoord").val(parseInt( y ) + 1);
    });     
    $("#left").click(function(){
        var y = document.getElementById('ycoord').value;
        var x = document.getElementById('xcoord').value;
        $(".move").animate({"left": "+=120px", "top": "+=60px"}, 500);
        changeImg(x, y, 'left');
        $("#xcoord").val(parseInt( x ) - 1);
    });
     $("#right").click(function(){
        var y = document.getElementById('ycoord').value;
        var x = document.getElementById('xcoord').value;
        $(".move").animate({"left": "-=120px", "top": "-=60px"}, 500);
        changeImg(x, y, 'right');
        $("#xcoord").val(parseInt( x ) + 1);
    });

function changeImg(x, y, move){
    $.ajax({
        type: "POST",
        url: "addImage.php",
        data: 'x=' + x + '&y=' + y + '&move=' + move,  
        cache: false,
        success: function(html){
            $(html).appendTo($("#tileView"));
        }
    });
    $.ajax({
        type: "POST",
        url: "removeImage.php",
        data: 'x=' + x + '&y=' + y + '&move=' + move,  
        cache: false,
        success: function(xml){             
            $("removeTile",xml).each(function(id) {    
            removeTile = $("removeTile",xml).get(id);
            removeID = $("tileID",removeTile).text();
            $("#" + removeID).remove();
        });
        }
    });
}
});
</script>

The ajax calls addImage.php to add a new row on the right spot and deleteImage.php to delete the row that's now out of view (i found without deleting those rows that things started running pretty slow).

In add image you just figure out the new position and output 's for the html to add in the page. For example part might look like this (but set the variables depending on move then go through the loop):

if($_REQUEST["move"] == "up") {
    $xmin = $x - 5;
    $xmax = $x + 5;
    $y = $y - 6;

    $left = 360;
    $top = -360;

    for($i = $xmin; $i <= $xmax; $i++) {
        $id = "T" . $i . "_" . $y;
        $newTiles .= "<div class='move' style='position:absolute; left:" . $left . "px; top:" . $top . "px;' id='$id'><img src='./Map/TileGroup1/1-$i-$y.gif'></div>\n";
        $left += 120;
        $top += 60;
    }
}

then just echo $newTiles out for your script to use.

Delete is similar, just putting out in xml the DIV ID's to delete because i couldn't get each() to work otherwise.

if($_REQUEST["move"] == "up") {
    $xmin = $x - 5;
    $xmax = $x + 5;
    $y = $y + 5;

    echo "<?xml version=\"1.0\"?>\n";  
    echo "<response>\n";  
    for($i = $xmin; $i <= $xmax; $i++) {
        echo "\t<removeTile>\n";
        echo "\t\t<tileID>T" . $i . "_" . $y . "</tileID>\n";
        echo "\t</removeTile>\n";
    }
    echo "</response>"; 
}

Hope this helps someone. Thank you all for the ideas and support!

I think you need to go back to the approach of the whole grid being nested in a DIV with overflow:hidden but use JavaScript to figure out which images should be visible and only load those images in as needed, then load in additional relevant images as the user scrolls to that area.

Scrolling of course should just manipulate the left and top CSS properties for your grid to move it with in the containing overflow: hidden DIV. In your case, it would be easiest to being by just changing the positioning CSS properties in increments of your tile size (so you never have portions of tiles showing).

From a programming standpoint this is a bit of a pain to do but it sounds like you've already got a method to calculate which ones are/should be displaying?

With this method, it will have that initial glitch as images are being loaded for the first time, but subsequent moving of the grid won't have to reload the same images. Once you've got this working, you can use jQuery or similar to animate the left and top properties to give a smooth scrolling effect.

Then, if you want, you can build on this further and allow partial scrolling of tiles and click-and-drag scrolling like Google Maps. Also if you want to work on performance, I'd recommending setting up an nginx server that listens on a few sub-domains of your site to serve up the tile images.


I haven't used this before, but maybe something like TileMill could work?

Why does eval() exist?

12 votes

Many programmers say it is a bad practice to use the eval() function:

When is JavaScript's eval() not evil?

I'd like to take a moment to address the premise of your question - that eval() is "evil"...

Is this eval() dangerous?

Buggy evaled code can violate security properties just as easily as buggy source code...

Why not eval() JSON?

There are a number of ways that your security may be compromised...

Is there ever a good reason to use eval()?

Yes - when there is no other way to accomplish the given task with a reasonable level of clarity... This eliminates 99% of cases where eval is used...

Why is eval unsafe in javascript?

The danger of eval only rears its ugly head when you are serving a script written by alice to user bob for bob's browser to eval...


So why does it exist in the first place?

Because sometimes there is a need. All the same reasons for/against using eval in JavaScript can likely be shared with the use of reflection in Java, for example.

However, I agree with everything you quoted in your question. Many reasons for using it are ill-advised, and best done differently - but sometimes, there is still a need, or it is simply the "best choice" over other available alternatives. (I'd focus on the answers to Is there ever a good reason to use eval()? for additional reasons.)

+1 to your question for good research.

How to make double click & single click event for link button of Asp.net control?

11 votes

Consider the following:

protected void dgTask_RowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        LinkButton btn = (LinkButton)e.Row.Cells[4].FindControl("lnkBtnEdit");

        btn.Attributes.Add("onclick", "return Test();");
    }
}

Instead of a single click, how can I make it double click while clicking on the link button?

Edited

I have tried with the solution presented by *competent_tech* but the problem is that in that case it will intercept the single click.

I need to do some operation on single click and something else on double click. Please help me.

Thanks

You'd have to do something like this.

Code behind.

Linkbutton btn;
btn.Attributes.Add("onClick", "OnClick();");

then in your javascript you'll need to define the OnClick function like this

var clickCount = 0;
var timeoutID  = 0;

function OnClick()
{
    clickCount++;

    if (clickCount >= 2) {
       clickCount = 0;          //reset clickCount
       clearTimeout(timeoutID); //stop the single click callback from being called
       DoubleClickFunction();   //perform your double click action
    }
    else if (clickCount == 1) {
       //create a callback that will be ran in a few miliseconds
       //to allow the user time to click again if they are double clicking

       var callBack = function(){ 
                         //make sure this wasn't fired at
                         //the same time they double clicked
                         if (clickCount == 1) {      
                            clickCount = 0;         //reset the clickCount
                            SingleClickFunction();  //perform your single click action
                         }
                      };

       //This will call the callBack function in 1/2 a second.
       //If by that time they haven't clicked the LinkButton again
       //We will perform the single click action. You can adjust the
       //Time here to control how quickly the user has to double click.
       timeoutID = setTimeout(callBack, 500); 
    }
}

You can either put the javascript directly into your .aspx file or add it dynamically when you add the LinkButton to the page. If you need to perform some action on the server side when the user single clicks or double clicks you can use the __doPostBack method. See here for more info on that.

The problem with my approach is that the user will always have to wait the entire callback time before their single click action is performed. I don't see any way around this as long as you are using single click/double click to distinguish what the user wants. If you find this delay to be too big of a problem you could always try something like click/shift+click to alternate between the actions. It probably wouldn't be as intuitive that way but you would immediately know what the user wants and could respond immediately instead of waiting to see if the user clicks a second time.

Let me know if you have any questions.

How often does JavaScript recompile regex literals in functions?

10 votes

Given this function:

function doThing(values,things){
  var thatRegex = /^http:\/\//i; // is this created once or on every execution?
  if (values.match(thatRegex)) return values;
  return things;
}

How often does the JavaScript engine have to create the regex? Once per execution or once per page load/script parse?

To prevent needless answers or comments, I personally favor putting the regex outside the function, not inside. The question is about the behavior of the language, because I'm not sure where to look this up, or if this is an engine issue.


EDIT:

I was reminded I didn't mention that this was going to be used in a loop. My apologies:

var newList = [];
foreach(item1 in ListOfItems1){ 
  foreach(item2 in ListOfItems2){ 
    newList.push(doThing(item1, item2));
  }
}

So given that it's going to be used many times in a loop, it makes sense to define the regex outside the function, but so that's the idea.

also note the script is rather genericized for the purpose of examining only the behavior and cost of the regex creation

There are two "regular expression" type objects in javascript. Regular expression instances and the RegExp object.

Also, there are two ways to create regular expression instances:

  1. using the /regex/ syntax and
  2. using new RegExp('regex');

Each of these will create new regular expression instance each time.

However there is only ONE global RegExp object.

var input = 'abcdef';
var r1 = /(abc)/;
var r2 = /(def)/;
r1.exec(input);
alert(RegExp.$1); //outputs 'abc'
r2.exec(input);
alert(RegExp.$1); //outputs 'def'

The actual pattern is compiled as the script is loaded when you use Syntax 1

The pattern argument is compiled into an internal format before use. For Syntax 1, pattern is compiled as the script is loaded. For Syntax 2, pattern is compiled just before use, or when the compile method is called.

But you still could get different regular expression instances each method call. Test in chrome vs firefox

function testregex() {
    var localreg = /abc/;
    if (testregex.reg != null){
        alert(localreg === testregex.reg);
    };
    testregex.reg = localreg;
}
testregex();
testregex();

It's VERY little overhead, but if you wanted exactly one regex, its safest to only create one instance outside of your function

Is it possible to change text color based on background color using css?

10 votes

Is it possible to change text color based on background color using css?

Like in the this image

http://www.erupert.ca/tmp/Clipboard01.png

As the text crosses over from one div (white-space:nowrap) is it possible to change the text color using css or jquery/javascript?

Thanks

Here is my solution (thinking it through a different way):

Use a DIV with overflow: hidden; for the navy 'bar' that shows the rating scale. You then write out two sets of TEXT:

  1. Inside the DIV bar (overflow: hidden;), it would be white (on top)
  2. In the underlying DIV container, it would be black. (container)

The result would be an overlap of the two colored text divs:

 ________________________________
|          1          |    2     |
|_(dark blue w white)_|__________|

Here is my jsFiddle

It works great because it will 'cut through' letters if the bar is at that width. Check it out, I think its what you are looking for.

Why does the "g" modifier give different results when test() is called twice?

10 votes

Given this code:

var reg = /a/g;
console.log(reg.test("a"));
console.log(reg.test("a"));

I get this result:

true
false

I have no idea how this could happen. I have tested in both Node.js (v8) and Firefox browser.

To workaround the problem, you can remove the g flag or reset lastIndex as in

var reg = /a/g;
console.log(reg.test("a"));
reg.lastIndex = 0;
console.log(reg.test("a"));

The problem arises because test is based around exec which looks for more matches after the first if passed the same string and the g flag is present.

15.10.6.3 RegExp.prototype.test(string) # Ⓣ Ⓡ

The following steps are taken:

  1. Let match be the result of evaluating the RegExp.prototype.exec (15.10.6.2) algorithm upon this RegExp object using string as the argument.
  2. If match is not null, then return true; else return false.

The key part of exec is step 6 of 15.10.6.2:

6. Let global be the result of calling the [[Get]] internal method of R with argument "global".
7. If global is false, then let i = 0.

When i is not reset to 0, then exec (and therefore test) does not start looking at the beginning of the string.

This is useful for exec because you can loop to handle each match:

 var myRegex = /o/g;
 var myString = "fooo";
 for (var match; match = myRegex.exec(myString);) {
   alert(match + " at " + myRegex.lastIndex);
 }

but obviously it isn't so useful for test.

var x = x || "default val" not getting set properly if x is defined above it

10 votes

HTML:

<script type="text/javascript">
  var x = "overriden";
</script>
<script src="myjs.js"></script>

myjs.js:

$(document).ready(function(){
  var x = x || "default val";
  alert(x); // this alerts "default val" and not "overriden"
});

For some reason, x is ending up as "default val" and not "overriden", even tho initially I'm setting it to "overriden" before I even include the script reference to myjs.js.

Any idea as to why this is happening? I'm trying to enable the hosting page to set an override for a variable that's used in an included js file, otherwise use the default val.

What you have after variable declaration hoisting is applied:

var x;
x = 5;

$(document).ready(function(){
    var x;
    x = x || "default";
});

It looks at the closest x and sees it's value is undefined which is a falsy value, so x gets set to "default".


You would be fine if they were in the same scope, because the declarations are always hoisted above assignments so:

var x = 5;

var x = x || "default";

Is actually just

var x;

x = 5;
x = x || "default";

This was suggested which is completely pointless:

$(document).ready(function(){
    x = x || "default";
});

It will throw a ReferenceError if x is not defined.


So either do the check in the same scope or do something like:

$(document).ready(function(){
    var x = window.x || "default";
});

Invalid property reads don't cause a ReferenceError but just return undefined instead.