Protovis - What are these functions with no curly braces? [duplicate] - javascript

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Lambda function syntax in JavaScript without curly braces
Dealing with Protovis - they implement some strange delegate functions which are given without curly braces - can someone shade a light on it for me, please?
Example:
vis.add(pv.Label)
.data(cols)
.left(function() this.index * w + w / 2)
.top(0)
.textAngle(-Math.PI / 2)
.textBaseline("middle");

In general, as explained in the question #missingno linked to, this is an alternate syntax for declaring functions, primarily supported by Firefox. Instead of:
function() { return "stuff" };
you omit the curly braces and return statement:
function() "stuff";
The end of the function occurs anywhere that a normal statement might end - a semicolon (;), a comma (,), or a close parenthesis ()).
In Protovis, there are a lot of cases where you need to declare short, one-statement anonymous functions to pass in as arguments to method calls. This is such a common pattern that that library includes a parsing utility to make sure that the above syntax is supported in browsers other than Firefox. If you enclose your Protovis code in script tags like this:
<script type="text/javascript+protovis">
// ...
</script>
the script will be evaluated by the Protovis parser, which ensures support for the special syntax.
My two cents on this: The upside of this syntax is that it's really fast (plus all the examples use it). A typically script using Protovis involves a lot of anonymous functions, so this can save you some typing, and it looks pretty awesome. When I first started using Protovis, I used it a lot - not just in method calls, but in variable declarations as well.
But, it has a few really heavy problems:
Because all your code is run through the Protovis parser, which essentially munges the code to re-add the return statements and then eval() it, it becomes fantastically hard to debug simple syntax errors. You get all these "Unexpected identifier" errors pointing to the eval() line in the Protovis code, with no indication of where the issue (a missing semicolon, etc) is occurring in your own code.
If you want your code to work outside Firefox, you have to include all your code in the special javascript+protovis script tags, which means no external files. Once you start doing anything of even marginal complexity, you really want to keep your scripts separate most of the time.
As with any "clever" syntax, it can get really hard to read, especially when you're using it in unexpected ways (e.g. outside of a method call). Yes, it's concise, but there's a definite price to pay in legibility.
All that said, I still use it when I want to make a rough sketch quickly. But most of the time, I'd suggest sticking to normal script tags and standard, curly-braced function declarations.

Related

Colon after colon syntax while calling a function in Javascript [duplicate]

This question already has an answer here:
Colon after function declaration in javascript [duplicate]
(1 answer)
Closed 4 years ago.
I came across a syntax somewhere on the web recently and couldn't grasp its meaning.
What I understand is that when we write props: Object inside the brackets, it means we're assigning a default value to props as Object. But what does the 2nd colon signify? It looks like a key-value pair but is confusing me still.
Tried searching on the web but wasn't able to search due to lack of terminology. Any ideas what this means?
someFn(props: Object): Object {
return someOtherFn(props);
}
These are type annotations. They are not standard javascript. They are added when using tools that layer static typing onto javascript. The two most popular flavors are Typescript and Flow.
When you write code that uses this syntax you will transpile your source code into code that is syntactically valid for execution by running one of the above mentioned tools on your code. When you do, it will tell you if your usage of the types is correct, raise warnings that are helpful in development, and then strip all this out so it can actually be run.

Are commas necessary in Node.js?

Are there risks incurred when omitting commas in variable declarations for node.js? For example, declaring some global variables like the following works just fine:
express = require('express')
jade = require('jade')
And I don't want to write commas if it's safe not to write them (I don't care about "beauty/clarity of code" arguments).
Important: I mean commas, not semicolons (got 3 answers about semicolons). It's perfectly OK and even recommended to remove semicolons from node.js. The creator of npm also does it: http://blog.izs.me/post/3393190720/how-this-works
If in doubt, check the latest javascript specs: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
Note that you also don't need to write
var
for global variables.
But this question is about "commas" so please don't replace commas by semicolons by mistake when editing my question (done before).
In JavaScript, if you don't write semicolons ; they will be inserted for you, invisibly. And you may not always like where they go.
You are not technically required to end every statement with a semicolon. However, most consider it a good idea.
For more info, peruse through the results of this google search. We've been arguing about this topic for a long time.
Here's an example of why this is more complex than it appears at first glance. While you are not technically required to end every statement with a semicolon, there are a few cases where you MUST, or things break. You cannot completely omit them in most codebases.
foo.def = bar
(function() {
// some self executing closure
})()
Looks simple enough right? Well the interpreter looks at that and does this:
foo.def = bar(function() {
// some self executing closure
})()
Which is probably not what you were expecting. The way to fix it, is with a semicolon.
foo.def = bar;
(function() {
// some self executing closure
})()
There a lot of cases like this. You can either learn them all, and only use them in those cases, and when you inevitably forget you try to debug your code that's doing something so strange and bizarre that you tear your hair out hours... "what do you mean wtfvar is not a function?!? It's not supposed to be a function!"
Or you can just use semicolons with consistency.
In short, no. The problems you are likely to run into will arise when you go to do things like code minifying and the compiler thinks that your two statements are one. Anyhow, if you choose not to use commas/semicolons, which is absolutely not recommended, you should be fine.
Node.js uses the V8 engine to read your code so it will pretty much behave like in Google Chrome. That said, not using semicolons is generaly a bad practice. The interpreter will try to understand your code and may be sometime mistaken (by your fault).
Check this out for a full explanation: Do you recommend using semicolons after every statement in JavaScript?
This very late answer just goes to clear confustion for others that might read this.
Since you're actually talking about commas, not semi-colons, I can only assume that you have a misunderstanding of what is implicitly being added by the engine.
Commas are not optional. And this code:
express = require('express')
jade = require('jade')
is being implicitly converted into this:
var express = require('express');
var jade = require('jade');
not this, which you might be expecting:
var express = require('express'),
jade = require('jade');

How to keep "*/" in regular expression from being interpreted as block comment?

I'm working on a bookmarklet which is using the replaceText plugin to wrap all words (and extraneous spaces/punctuation) on a page in span tags. That plugin traverses all the text nodes on a page and allows me to call a function to manipulate the contents of each one without breaking any other HTML formatting on the page. (None of this is the problem, I'm pretty sure, but I felt like the context might be useful). My call of the function looks like this, for your reference:
$("body *").replaceText(/\S+\s*/g, spanWrap);
The problem is that the best regular expression I've found for separating these words for my purposes -- /\S+\s*/g -- contains the characters for the end of a block comment ("*/"). If I add the opening of a block comment a few lines before it in the .js file in Notepad++, I can see that the syntax highlighter is reading it as that.
When I run my bookmarklet, most sites seem to have no problem with this issue and the bookmarklet works as intended. However, some sites, for reasons I can't predict, throw up an "Uncaught SyntaxError: Unexpected token <" error and the bookmarklet breaks/stops running. If I change the regular expression I'm using in the replaceText function to one I had been using in an earlier version of the bookmarklet -- /\b(\S+?)\b/g -- while changing absolutely nothing else in the bookmarklet, these sites stop giving the error and the bookmarklet works just fine, so I have to believe that it's the presence of the block comment closure that's causing it.
For the purposes of what I'm trying to do with the bookmarklet, though, the expression with that comment closure in it --/\S+\s*/g-- works much, much better than the other one, which doesn't catch punctuation and white space. However, I'd also really like it if my bookmarklet didn't break on certain sites.
So, is there either a way to fix the regular expression that I have so that it's not being read as a comment or can you suggest one that can do the same job maybe with a different syntax or something? (If it's not obvious from my question, I have the barest understanding of how regular expressions work and have gotten the ones I'm using in this example by copying them from other Stack Overflow questions/answers)
Use the long version:
var regex = new RegExp("\\S+\\s*", "g");
$("body *").replaceText(regex, spanWrap);
(EDIT: Escaped the backslashes in the string)
So, is there either a way to fix the regular expression that I have so that it's not being read as a comment
I can't think of anything sane. (You could get the effect by using the RegExp constructor and breaking the regex up into two strings and then concatenating them back together for the regex. I wouldn't call that sane though.)
I'd use a series of line comments // instead of a block comment.

Javascript function declarations with a dollar sign

This function declaration doesn't make sense to me. What does the $ sign do?
function $(id) { return document.getElementById(id); }
Also, this code is interfering with other Javascript code. If I comment it out, then the other Javascript code I'm trying to use works, but then I lose some other functionality.
Why might it be interfering with my other code.
What does the $ sign do?
Nothing special. It is just a character that can be used in variable/function names.
There has been a trend to use $ as the name to the gateway function for a number of libraries (including Mootools, Prototype and jQuery). This has two major problems:
It makes them conflict with each other
It violates the principles of self-documenting code
Also, this code is interfering with other Javascript code.
Presumably something else is using a variable called $ then.
You are declaring a function called $ that wraps document.getElementById, apparently for convenience. Nothing special.
Reference What characters are valid for JavaScript variable names?
As for the interference, there is likely another global variable called $, which is being clobbered. See jQuery.
JavaScript variables can start (and only consist of) a $ (amongst others).
Previously, the $ was added solely for machine generated variables.
This was in the spec I believe, but has since been removed (don't quote me).
Dollar sign was added to the language specifically for use by code
generators and macro processes, so if you have machines writing code
then the machines need to be confident that the variables that they
create will not conflict with variables that the humans are going to
create. To distinguish them, we’ll allow the machines to use dollar
sign. Some of the ninjas found out about that and thought oh, dollar
sign, I can use dollar sign as a function name, so they’re out there
doing that. And it looks stupid. I mean, look at a program with dollar
sign.
Source: Douglas Crockford.
If it is interfering with other code, you may be using a library which uses this identifier. If that's the case, look at the no conflict mode for that library (if it has one).
Let me guess: are you using jQuery or prototype?
$ and _ are valid characters in variable/function names. The code is the same as declaring function a(id) {return document.getElementById(id);}.
It's typically used as a shortcut for selecting an element because typing document.getElementById is much too long for how often it's used.

What's the purpose of starting semi colon at beginning of JavaScript? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What does the leading semicolon in JavaScript libraries do?
I have noticed a lot of jQuery plugins start with
;(function(){ /* something in here */ })();
I just wondered what the beginning semi-colon was for, as well as the empty parentheses at the end.
The semi-colon is there in case you include this script just after some 'bad' script that doesn't properly close off its last line with a semi-colon. In this case it's possible the two scripts would be combined and result in invalid code. For example if you are merging multiple script into a single response.
The () at the end is executing the function. This is creating a closure. Private variables and methods can be declared within the scope of this function that cannot be accessed from outside the script.
This construct :
(function(){ /* something in here */ })()
Is used to create a new scope in Javascript.
More info on function scope here.
Regarding the semicolon, I never seen it before. I think it's a security for when you concatenate several scripts, since semicolons are optional in some cases at the end of the file.

Categories

Resources