JavaScript Functions — In-Depth

Last week I talked about JavaScript variables gotchas.  This week, we want to take an in-depth look at JavaScript functions.

Why?

Well, for the same reason we looked at variables last week.  If you keep using JavaScript the way you think it works instead of the way it really works, at best, you will have a much harder time debugging your JavaScript code.  Worse case, you introduce some pretty nasty bugs into your code.

So, let’s start with a pretty basic JavaScript function question.  One I would use as a question if I were interviewing someone for a hardcore JavaScript job.

What is the difference between the following two ways of declaring a function?

function foo(){
}
var foo = function(){
}

JavaScript Functions -- In-depth

Declaring JavaScript Functions

If you think these both do the same thing, you would be almost right.  But here is the key distinction.

Remember our discussion last week about variable hoisting?

When you declare a variable, the declaration is hoisted to the top of the variable scope but it isn’t assigned to the actual assignment in the code.

So that the following code

var foo = function(){
}

Actually compiles to

var foo;
// other code may occur here
foo = function(){
}

On the other hand, if you declare functions using

function foo(){
}

What happens is that the variable is both declared and assigned at the top of the variable scope.

In fact, when you use this second method to declare a function, the variable gets declared prior to variables declared with the var keyword.

Why Does This Matter?

“So,” I hear you thinking, “why the fuss?  My code runs either way.”

Or does it.

If you use var foo() instead of function foo(), you can run into a situation where you have one function calling another function before the function variable has been assigned the function pointer.  It doesn’t happen often, and it happens a lot less frequently when you are doing “object oriented” JavaScript, but it can happen.

Here is an example:

var foo = function(){
   bar();
}
foo();
var bar = function() {
}

Yeah, I know, wrong on so many levels.  But this is how bad code happens.  Implementing best practices at multiple levels makes the code more solid.

If we rewrite the code to see what is happening the problem becomes clear.

var foo;
var bar;
foo = function(){
    bar();
}
foo();
bar = function(){
}

Bar is getting called before we ever assign the function to it.

But by simply rewriting this using function declaration, we avoid the issue:

function foo(){
   bar();
}
foo();
function bar() {
}

When we rewrite this as it will compile, we see that we no longer have an issue:

function foo() {
    bar();
}
function bar(){
}
foo();

Anonymous Functions

A discussion on JavaScript functions would not be complete if we didn’t address the subject of anonymous functions.

Anonymous functions are functions that show up most often as parameters to other functions.  Rather than declaring a function and passing the function in as a variable pointing to the function

function callBackFoo(){
}
function mainFoo(callBack){
    callBack();
}
mainFoo(callBackFoo);

We get lazy and just write the function as part of the parameter.

function mainFoo(callBack){
    callBack();
}
mainFoo(function(){});

And here again, I hear you thinking, “Yep.  Do that all the time.  What’s wrong with that?”

The Problem with Anonymous Functions

Well, there are two problems.

First, when you use an anonymous function and an exception is thrown.  If your anonymous function is part of the call stack for the exception, all you will see in your debugger is something about “anonymous” because it doesn’t have a name associated with it.  Yes, you’ll get a filename and a line number.  But you’ll have to go look at the code to see what function caused the problem.

The second, and I think more compelling, issue with anonymous functions is “Callback Hell.”

You know, a function that takes a callback that calls a function that takes a callback … etc.

If you haven’t seen this yet, you haven’t coded anything significant in JavaScript yet.

This isn’t to say that I haven’t used these same shortcuts.  But they ARE issues you need to consider.  At least when I take the shortcut, I think to myself, “Is the pain really worth it?”

Immediately Invoked Function Expressions (IIFE)

Pronounced “iffy” the Immediately Invoked Function Expression is the one place where I think anonymous functions serve a very helpful purpose.

The basic structure of an IIFE looks like this:

(function(){
    // code goes here.
})();

Or, if you prefer

(function(){
    // code goes here.
}());

The first way makes more sense to me.  But whatever.

The idea is that we’ve created an anonymous function and executed it right away.  It is the same as if we had written:

function foo(){
    // code goes here
}
foo();

But, by doing this, we’ve introduced a variable into our scope that we only plan to use once.  If we are doing this in our global namespace, we could be stomping over an existing variable we might want later.

Imagine if you were using jQuery and wrote:

function $(){
}
$();

or worse

var $ = function(){
}
$();

So, IIFEs take care of this issue.  It keeps all of the variables we declare in a file out of global scope while still making them accessible to all of the functions we declare within the IIFE.  Since it runs at load time, we really don’t need a function name for our debug stack.

A Note About JavaScript and Node.js

While everything I’ve said above is true for browser-based JavaScript.  When you get into the area of Node.js development, the rules change slightly.  Specifically, each JavaScript file is already wrapped in an IIFE, this is why we need module.exports and why if you assign a variable in one JavaScript file it is not available to you to use in another JavaScript file.  So as far as I can think, there is no valid reason for using anonymous functions in Node other than laziness.  But I’m sure someone will set me straight in the comments.

JavaScript Functions Best Practices

All of this leads to the following best practices regarding the use of function in JavaScript

  1. Declare functions using the function keyword instead of the var keyword.
  2. Avoid anonymous functions
  3. Wrap globally accessible client side code in an IIFE to avoid polluting global variable scope.
原文:https://dzone.com/articles/javascript-functions-in-depth

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值