JavaScript Function Syntax Explanation: function object.myFunction(){..} - javascript

I would consider myself to be reasonably competent with JavaScript and familiar with many of the different ways of achieving the same thing. But today I came across some function syntax which I hadn't seen before:
function document.body.onload()
{
alert('loaded');
}
If I were to write such code I would have done it like this:
document.body.onload = function()
{
alert('loaded');
}
Ignoring the fact that this is not the best way to handle the onload event, is this actually valid JavaScript? It appears to causes syntax errors in FireFox (and JSLint), so I am guessing that it is Internet Explorer only syntax? If it is IE only then I would like to remove it but I am concerned that it might have some quirky side effect.

function document.body.onload is non-standard JavaScript syntax. Use the second format, and fire whomever wrote the original code.
Don't forget the semi-colon after the end }
document.body.onload = function () {
...code...
}; //this is easy to miss

No, it's not valid. the function X() {} variant requires that the name of the function only contains letters, digits, '$' and '_'.
If you want to check other syntax, you can get the standard here, but the syntax diagrams in the back of JavaScript: The Good Parts are much easier to digest.

Related

Why defining function inside an if is a bad idea?

From Eloquent Javascript by Marijn Haverbeke
Different JavaScript platforms in different browsers have
traditionally done different things in that situation, and the latest
standard actually forbids it.
but why is it bad?
function example () {
function a () {} // Okay
if ( something ) {
function b () {} // Danger !
}
}
It's considered "bad" because its behavior is inconsistent and sometimes doesn't do what most people would expect. Consider the following snippet:
if (true) {
function f() { return "t"; }
} else {
function f() { return "f"; }
}
What would calling f() return? On IE and Firefox, it will return "t", but on Chrome and Safari, it will return "f". Why? A combination of hoisting and JavaScript's scoping rules. For information on how that works, see this question on JavaScript scoping and hoisting.
Effectively, this means that, on some browsers, the branch is completely ignored when it comes to function definitions using the function name() { ... } form. If you really need to do something like this (and you probably don't, since it would be very poor style, anyway), use the name = function () { ... } form instead, since that will not be hoisted, so the behavior is well-defined and will not be inconsistent across platforms.
This is standardized in ES6 and is valid to nest function declaration inside blocks. Here is the spec Block-Level-Function-Declarations
You can try in latest browsers with strict-mode turned on.
And for reasons why that behavior is present in old environments look here:
Functions
The short answer is already given to you, namely: such practice negatively affects the portability/compatibility of the solution between various browsers. What is even worse: it leads to the added ambiguity regarding the local variables, namely: which variables will be "visible" to which nested functions. Even though it could be considered allowed technique, but it doesn't mean that such technique is a good practice. "Code for the clarity" is the utterly important programming paradigm, so always try avoiding the practices which add to the ambiguity. Best regards,

What exactly does !function ($){...}(window.jQuery) do?

I'd like to know exactly what's going on here. I know what $(document).ready(function() {...}); does and when it comes into effect. Same goes for jQuery(function($) {...}.
But what does this do?
!function ($) {
$(function(){
var $window = $(window)
//normal jquery stuff
})
}(window.jQuery)
Is it loaded when jQuery is loaded instead of when the document is 'ready'?
It creates a closure in which the variable $ is assigned the value of window.jQuery.
The intention is to allow the uninformatively named variable $ to be used as a shortcut for jQuery without conflicting with the large number of other libraries and custom functions that also use $ as a variable name.
Using the ! operator before the function causes it to be treated as an expression
!function () {}()
The syntax you're looking at is used for setting up a jQuery closure. This is used to ensure that the jQuery $ variable is garuanteed to be available and correct within the code; ie it can't be overwritten in the global scope by anything else (which is possible if you're using multiple libraries, etc).
This technique is often used by jQuery plugin authors -- if you're interested in finding out more, the docs are here, and explain in more detail why you'd want to wrap your jQuery code in a function like this.
The only point of interest that's different in your example is that in the docs, the function is wrapped in brackets, whereas in the example you've given it's preceded by a !
The ! is a not operator, but doesn't actually get used for anything; I think it's just there instead of the brackets to save a single character of code. Probably helpful if you're into minifying javascript.
Not quite sure but I guess this is somewhat equivalent to (function(){})() approach and it's about js closures. And it ensures $ and jQuery are the same thing
The '!' is a 'not' operator. It doesn't do anything in the code. The only reason it is there is to signify that the function will execute immediately.
You may also see functions wrapped in parenthesis instead.
(function() {}());
Whatever is used is personal preference.

replace js function keyword with f

I want to know if it's possible to do something like:
var f = function;
and than use f like it would be the js function keyword
if something like this would be possible I would use it for js code minimization, cuz I have a lot of function in my code
Similar to what Pointy pointed out in the comments, what you can do is use the function constructor to create a new function and pass it as string. In other words:
function f(s) { return new Function(s) };
var foo = f('var s = "hello"; return s');
alert(foo()); //=> "hello"
But again, I think this is unnecessary.
Edit: To add parameters you'd use the arguments object.
function f() {
var args = Array.prototype.slice.call(arguments);
var func = args.pop();
return new Function(args.join(','), func);
}
var add = f('a,b', 'return a + b');
It is not possible to do as you describe.
The closest I can think of is to make a function for generating functions, using eval to parse a passed string. Using eval however, is generally evil and should be avoided. Overall, I would not recommend doing something like this at all.
Also, it is worth noting that there is very little point in doing what you want, as javascript sent over the wire should be compressed first, so the the word function will be represented by one token, regardless of how long the word is.
If you want your source code to be more readable and concise, I would recommend coffee-script which compiles to javascript, and allows you to define functions without using even the first letter of function. Chuck Norris would approve!
Summary of conclusions and recommendations
use coffee-script for cruft free source
compile it to verbose javascript you never look at
minify that javascript (uglify is a great compressor, or google's closure)
gzip it (will compress repetitive strings well)
send it
The key issue here is that after it is gzipped, the size of the word function becomes irrelevant, so the only remaining issue is the readability of your source code.
Yeah...to be quite honest, I wouldn't worry about trying to shorten the function keyword to 'f' which gives you back very little for the work and it would also hurt the readability of your code. And, unless you have something like a million functions, I wouldn't focus on that. As #prodigitalson said - run it through a minifier. That should take care of the real minifications that are possible in your code and still maintain readability in your code base (which is more important than saving a few bytes).
Also, per my comment, there is something (potentially) on its way to replace the long 'function' keyword (something Brendan Eich has said he would have considered changing - you have to remember that he designed the language in 10 days or so). Read more about it here: Fat Arrow Syntax Of course, these sorts of things can always change...but the standards definition bodies are looking at it.
You could do this with the hygenic macro functionality of http://sweetjs.org/

Javascript function() literal overloading

I was always curious is there any possibility to overload function literal, something like you can do with Function:
var test=Function;
Function=function(arg)
{
alert('test');
return test(arg);
}
var b=Function("alert('a')");
var c=Function("alert('x')");
b();
c();
Of course you can guess that this is nice way of debugging whole project. However any effort I made here goes for nothing.
Question for you experts is:
Maybe there is something that i don't know, maybe there is possibility to overload this damn constructor? (but probably not).
If not then - how to do this - if this possible - in any of browser (not just by using javascript - but their extended language - every browser got something like this).
If not then - how this is done trough addOn like firebug or etc. ??
You're terminology is off: Function() is the function constructor, whereas function() {...} is a function literal.
And no, I don't think there's a portable way to do this, but there might be for old versions of Firefox: If I remember correctly, it once was possible to use with() {...} to shadow the built-in constructor functions and Firefox would use the new ones even for literals.
This seems to work no longer:
var overload = {
Object : function() {}
};
overload.Object.prototype.foo = 'bar';
with(overload) {
document.writeln(new Object().foo);
document.writeln({}.foo);
}

Which of these cross-browser Javascript functions performs better?

As a rule of thumb, which of these methods of writing cross-browser Javascript functions will perform better?
Method 1
function MyFunction()
{
if (document.browserSpecificProperty)
doSomethingWith(document.browserSpecificProperty);
else
doSomethingWith(document.someOtherProperty);
}
Method 2
var MyFunction;
if(document.browserSpecificProperty) {
MyFunction = function() {
doSomethingWith(document.browserSpecificProperty);
};
} else {
MyFunction = function() {
doSomethingWith(document.someOtherProperty);
};
}
Edit: Upvote for all the fine answers so far. I've fixed the function to a more correct syntax.
Couple of points about the answers so far - whilst in the majority of cases it is a fairly pointless performance enhancement, there are a few reasons one might want to still spend some time analyzing the code:
Has to run on
slow computers, mobile devices, old
browsers etc.
Curiosity
Use the same
general principal to performance
enhance other scenarios where the
evaluation of the IF statement does
take some time.
Unless you're doing this a trillion times, it doesn't matter. Go with the one that is more readable and maintainable to you and/or your organization. The productivity gains you will get from writing clean, simple code matters way more than shaving a tenth of a microsecond off your JS execution time.
You should only even start thinking about what performs better when and only when you've written code and it is unacceptably slow. Then you should start tracking down the bottleneck, which will never be something like this. You will never get a measurable performance gain out of switching from one to the other here.
Unfortunately the code above is not actually cross-browser friendly as it relies on a mozilla quirk not present in other browsers -- namely that function statements are treated as function expressions inside branches. On browsers other that aren't built on mozilla the above code will always use the second function definition. I made a simple testcase to demonstrate this here.
Basically the ECMAScript spec says that function statements are treated similarly to var declarations, eg. they all get hoisted to the top of the current execution scope (eg. the start of a <script> tag, the start of a function, or the start of an eval block).
To clarify olliej's answer, your second method is technically a syntax error. You could rewrite it this way:
var MyFunction;
if(document.browserSpecificProperty) {
MyFunction = function() {
doSomethingWith(document.browserSpecificProperty);
};
} else {
MyFunction = function() {
doSomethingWith(document.someOtherProperty);
};
}
Which is at least correct syntax, but note that MyFunction would only be available in the scope in which that occurs. (Omit var MyFunction;, and preferably use window.MyFunction = function() ... for global.)
Technically, I would say that the second one would perform better, because the if statement is only executed once, rather than every time the function is run.
The difference, however, would be negligible to the point of being meaningless. The performance penalty of a single if statement such as this would be insignificant even compared to the performance penalty of simply calling a function. It would make a smallish difference even if if is called a million times.
The first one is easier to understand, because it doesn't have the awkwardness of defining the same function twice based on a condition, with both versions behaving differently. That seems to be a recipe for confusion later on.
I wouldn't be the first person to say that unless you are really insane about this optimization thing, you'll get more of a win out of code readability.
I generally prefer the second version, as the condition only has to be evaluated once and not on every call, but there are times when it's not really feasible because it will hamper readability.
Btw, this is a case where you might want to use the ?: operator, e.g (taken from production code):
var addEvent =
document.addEventListener ? function(type, listener) {
document.addEventListener(type, listener, false);
} :
document.attachEvent ? function(type, listener) {
document.attachEvent('on' + type, listener);
} :
throwError;
For your simplified example I would do what's below assuming that your browser property check only needs to be done once:
var MyFunction = (function() {
var rightProperty = document.browserSpecificProperty || document.someOtherProperty;
return function doSomethingWith() {
// use the rightProperty variable in your function
}
})();
The performance should be nearly equal!
Thing about using Frameworks like JQuery to get rid of the Browser compability problems!
If performance is your main goal, have a look at SlickSpeed! It is a page which benchmarks different JavaScript frameworks!

Categories

Resources