标签云

微信群

扫码加入我们

WeChat QR Code

VAR函数名= function() { }与{ }功能functionname()

I've recently started maintaining someone else's JavaScript code. I'm fixing bugs, adding features and also trying to tidy up the code and make it more consistent.

The previous developer uses two ways of declaring functions and I can't work out if there is a reason behind it or not.

The two ways are:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

What are the reasons for using these two different methods and what are the pros and cons of each? Is there anything that can be done with one method that can't be done with the other?


permadi.com/tutorial/jsFunc/index.html is very good page about javascript functions

2018年05月23日41分05秒

Related is this excellent article on Named Function Expressions.

2018年05月23日41分05秒

CMS references this article: kangax.github.com/nfe/#expr-vs-decl

2018年05月23日41分05秒

There are two things you need to be aware of: #1 In JavaScript, declarations are hoisted. Meaning that var a = 1; var b = 2; becomes var a; var b; a = 1; b = 2. So when you declare functionOne, it gets declared but its value isn't set immediately. Whereas since functionTwo is just a declaration, it gets put at the top of the scope. #2 functionTwo lets you access the name property and that helps a lot when trying to debug something.

2018年05月23日41分05秒

Oh and btw, the correct syntax is with a ";" after the assignation and without after the declaration. E.g. function f(){} vs var f = function(){};.

2018年05月23日41分05秒

Greg: By the way, the difference isn't only that they are parsed at different times. Essentially, your functionOne is merely a variable that has an anonymous function assigned to it, whereas functionTwo is actually a named function. Call .toString() on both to see the difference. This is significant in some cases where you want to get the name of a function programmatically.

2018年05月23日41分05秒

There are both different. The first one is a function expression the second one is a function declaration. You can read more on the topic here: javascriptweblog.wordpress.com/2010/07/06/…

2018年05月23日41分05秒

Greg The part of your answer concerning parse time vs. run time is not correct. In JavaScript, function declarations are not defined during parse time, but during run time. The process goes like this: Source code is parsed -> JavaScript program is evaluated -> The global execution context is initialized -> declaration binding instantiation is performed. During this process the function declarations are instantiated (see step 5 of Chapter 10.5).

2018年05月23日41分05秒

The terminology for this phenomenon is known as hoisting.

2018年05月23日41分05秒

This answer has nothing on Eugene's. And it's quite misleading with the parse-time vs run-time statement.

2018年05月23日41分05秒

I refer to RoBorg but he is nowhere to be found. Simple: RoBorg === Greg. That's how history can be rewritten in the age of internet. ;-)

2018年05月23日41分05秒

var xyz = function abc(){}; console.log(xyz === abc); All browsers I've tested (Safari 4, Firefox 3.5.5, Opera 10.10) gives me "Undefined variable: abc".

2018年05月23日41分05秒

Overall I think this post does a good job of explaining the differences and the advantages of utilizing the function declaration. I'll agree to disagree as far as the benefits of utilizing function expression assignments to a variable especially since the "benefit" seems to be an advocation of declaring a global entity... and everyone knows that you shouldn't clutter the global namespace, right? ;-)

2018年05月23日41分05秒

imo a huge reason to use named function is because debuggers can use the name to help you make sense of your call stack or stack trace. it sucks when you look at the call stack and see "anonymous function" 10 levels deep...

2018年05月23日41分05秒

Antimony A function declaration is not the same thing as a block. This should explain better: stackoverflow.com/questions/17409945/…

2018年05月23日41分05秒

then the name w is simply ignored ?

2018年05月23日41分05秒

PellePenna: Function names are useful for lots of things. The two biggies in my view are recursion, and the name of the function being shown in call stacks, exception traces, and such.

2018年05月23日41分05秒

This should now be the accepted answer. It's much more recent than the one above.

2018年05月23日41分05秒

ChaimEliyah - "Accepting doesn't mean it's the best answer, it just means that it worked for the person who asked." source

2018年05月23日41分05秒

A.R.: Quite true. Amusingly, though, right above that it says "The best answers show up first so that they are always easy to find." Since the accepted answer shows up first even over higher-voted answers, the tour might be somewhat self-contradicting. ;-) Also a bit inaccurate, if we determine "best" by votes (which isn't reliable, it's just what we've got), "best" answers only show up first if you're using the "Votes" tab -- otherwise, the answers that are first are the active ones, or the oldest ones.

2018年05月23日41分05秒

I did not know that functions could be overwritten in JavaScript! Also, that parse order is the big selling point for me. I guess I need to watch how I create functions.

2018年05月23日41分05秒

+0 to the "Names function expressions demystified" article as it's 404ing. Possible mirror?: kangax.github.com/nfe

2018年05月23日41分05秒

CMS Nice one. Bear in mind though I never saw the original so I don't know if that's a mirror or just another article with the same title!

2018年05月23日41分05秒

Mr_Chimp I'm pretty sure it is, thewaybackmachine is saying that it got a 302 at crawl time and the redirection was to the link you provided.

2018年05月23日41分05秒

HI suhail thanks for clear info about function topic. Now my question is which one will be the first declaration in declaration hierarchy whether variable declaration (functionOne) or function declaration (functionTwo) ?

2018年05月23日41分05秒

yuiblog.com/blog/2007/06/12/module-pattern is the primordial reference for the module pattern, as far as I can tell. (Though that article uses the var foo = function(){...} syntax even for private variables.

2018年05月23日41分05秒

This isn't entirely true in some older versions of IE, actually. (function window.onload() {} was a thing.)

2018年05月23日41分05秒

this example is good and is close to perfection, but could be improved. the better example would be to defined var myFunc = null; outside of a loop, or outside of an if/elseif/else block. Then you can conditionally assign different functions to the same variable. In JS, it is a better convention to assign a missing value to null, then to undefined. Therefore, you should declare myFunction as null first, then assign it later, conditionally.

2018年05月23日41分05秒

It appears this answer was merged into this question from another question, and the wording might seem to be a tiny bit unrelated to this question. Would you consider editing the answer so it seems more directed specifically at this question? (to reiterate; this isn't your fault at all... just a side-effect of a merged question). You can also delete it, and I think you would keep your reputation. Or you can leave it; since it's old, it may not make a big difference.

2018年05月23日41分05秒

ahm, your answer... isn't it ambiguous? well written though so +1 for spending and writing too much info.

2018年05月23日41分05秒

I'd say that maintainability is the most important aspect of most code. Performance is important, but in most cases IO is likely to be a bigger bottleneck that the way you define your functions. However there are some problems where you need every bit of performance you can get and this is useful in those cases. Also good to have an answer here that answers clearly a well defined part of the question.

1970年01月01日00分03秒

Well, I found it to be other way around with Firefox. jsperf.com/sandytest

2018年05月23日41分05秒

Microbenchmarks always fail. Looking to jsperf.com is waster of time. What you really need is to look to JS engine source code, official documentation, or at least sniff dev blogs or mail lists.

2018年05月23日41分05秒

Just an update, since I've gone full functional programming style in JavaScript now, I never use declarations, only function expressions so I can chain and call my functions by their variable names. Check out RamdaJS...

2018年05月23日41分05秒

SandeepNayak I just run your own test in Firefox 50.0.0 / Windows 7 0.0.0, and it actually is the same way as Leon's. So if your test is correct, I would conclude that jsperf's tests are not indicatives, and it all depend on your browser and / or OS version, or in the particular state of the current machine in that particular moment.

2018年05月23日41分05秒

You have a bit weird way to place the closing braces. Are you a Python coder? It looks like you try to make Javascript look like Python. I am afraid it is confusing for other people. If I had to maintain your JavaScript code I would let your code through an automatic prettyprinter first.

2018年05月23日41分05秒

Excellent post. A 'self-executing function' or 'immediately invoked function expression' should be easy enough to see and his style preference should not detract from his post - which is accurate and summarizes 'hoisting' perfectly. +1

2018年05月23日41分05秒

Your example is kind of the same as the top answer

2018年05月23日41分05秒

The main reason for posting this answer was to provide the link at the bottom. This was the piece that was missing for me to fully understand the above question.

2018年05月23日41分05秒

It's very cool that you wanted to share the link. But links to additional information, in SO, should just be a comment on either the question or your favorite answer. It's very much sub-optimal to clutter a long, complicated page like this with repeated information just to add a single useful link at the end of it. No, you won't get rep points for providing the link, but you'll be helping the community.

2018年05月23日41分05秒

There are the test to confirm: blog.firsov.net/2010/01/… JS performance test - scope and named functions - Analytics

2018年05月23日41分05秒

Sorry but this is incorrect - I don't know what Crockford is trying to say in that slide. Both function & variable declarations are always hoisted to top of their scope. The difference is that variable assignments (whether you are assigning it with a string, boolean or function) are not hoisted to the top whereas function bodies (using function declaration) are.

2018年05月23日41分05秒

Have a look at these code examples: gist.github.com/cyberthom/36603fbc20de8e04fd09

2018年05月23日41分05秒

Just calling this.yell works too :)

2018年05月23日41分05秒

The name in the first case will not be defined because its an anonymous function assigned to a variable. I think the word anonymous was invented for things that don't have their name defined :)

2018年05月23日41分05秒

In this example the two=new becomes a global function because no var

2018年05月23日41分05秒

I can't seem to reproduce this. console.log(objectOne.__proto__); prints "functionOne {}" in my console. Any ideas of why this may be the case?

2018年05月23日41分05秒

I can't seem to reproduce it as well.

2018年05月23日41分05秒

This is a capability of your debugger (to display the "class" of the logged object), and most ones are able to derive a name even for anonymous function expressions these days. Btw, you should make clear that there is no functional difference between the two instances.

2018年05月23日41分05秒

Arjun What's the problem if a question was asked years earlier ? An answer doesn't only benefit the OP but potentially all SO users, no matter when the question was asked. And what's wrong with answering questions that already have an accepted answer ?

2018年05月23日41分05秒

Arjun you got to understand answering old questions is not bad. If it were to be, SO would have had such a barrier. Imagine there is a change in API(albeit not in this question's context) and someone spots it and provides an answer with the new API, shouldn't that be allowed?? Until and unless the answer doesn't make sense and doesn't belong here, it would be downvoted and removed automatically. You don't need to bother with it!!!!

2018年05月23日41分05秒

what about the third option, var fn = function fn() {...}?

2018年05月23日41分05秒

Hi Chharvey, not sure about ur question, I guess u r talking about function expression which I have already mentioned. However, if still there is some confusion just be more elaborative.

2018年05月23日41分05秒

yes I was asking about a named function expression. it's similar to your option #2 except that the function has an identifier. usually this identifier is the same as the variable it's being assigned to, but that's not always the case.

2018年05月23日41分05秒

Yes Named function expression is similar to my option #2. Well having an identifier is not mandatory as it's not used. Whenever you will be executing the function expression you will use the variable holding the function object. Identifier serves no purpose.

2018年05月23日41分05秒

...also this way of declaring is a better way to create Constructor functions in JavaScript , may you please elaborate, I'm curious!

2018年05月23日41分05秒

One reason is because all built-in Constructor functions in JavaScript created like this function Number() { [native code] } and you shouldn't be confused with built-in ones, also referencing later on in this case is safer and you end up neater code but not using hoisting...

2018年05月23日41分05秒

Yes, this difference is so insignificant that hopefully devs will concern themselves with which approach is more maintainable for their specific needs rather than which one might be faster (you'll get different jsperf results on each try depending on what the browser is doing -- the majority of javascript tasks needn't concern themselves with micro-optimizations to this degree).

2018年05月23日41分05秒

squidbe There is no difference. Look here: jsperf.com/empty-tests-performance

2018年05月23日41分05秒

Please elaborate and provide working code snippets

2018年05月23日41分05秒

While this is good and true, how exactly does this alone relate to the quesiton being asked?

2018年05月23日41分05秒