Function Smackdown: Function Statement vs. Function Expression

I’ve recently been reading ‘JavaScript: The Good Parts,’ by Douglas Crockford. This concise book defines a subset of core JavaScript that’s robust and powerful: The Good Parts. Appendix B identifies The Bad Parts, and sets our competitors - the function statement and the function expression - apart.

ROUND ONE - LOOKS (CAN BE DECEIVING)

Function Statement

Our competitors may look alike, but the function statement has two distinguishing characteristics: the declarative keyword function always comes first, and you must name it. Here’s what it looks like:

// What we see
function funcName(){}

  

Pull back the curtain, though, and the function statement expands into a variable with a function value:

// Under the hood
var funcName = function funcName(){}

  

Function Expression

Absent the mark of the function statement, you have the function expression. The function expression is optionally named (but normally anonymous), e.g.:

// Stores ref. to anonymous function in a variable
var funcRef = function(){};

// Stores ref. to named function in a variable
var funcRef = function funcName(){};

  

WINNER: Function Expression. Crockford’s manual argues the case for clear code. The function expression is clearly recognisable as what it really is (a variable with a function value).

ROUND TWO - (UNPREDICTABLE) BEHAVIOUR

Function Expression

Variables are subject to a thing called hoisting. Irrespective of their apparent place in the flow of things, their var part is removed and hauled to the top of a containing (whether function or global) scope, and initalised with undefined:

// What we see
var funcRef = function(){};

// Under the hood
var funcRef = undefined;
funcRef = function(){};

  

Function Statement

The function statement - while just shorthand for a var statement with a function value - is treated differently: the whole lot is hoisted. For this reason, you can call a function statement before you have declared it in your code:

console.log(statement()); // I am a function statement.
console.log(expression()); // TypeError...

function statement(){
  return "I am a function statement.";
}

var expression = function(){
  return "I am a function expression.";
}

  

WINNER: Function Expression. Hoisting is already a behind-the-scenes behaviour that can cause head scratching. The particular behaviour of the function statement can lead to more furious head scratching.

ROUND THREE - SUPER POWERS

Function Statement

The function statement is widely used and performs just fine, but it has an obvious limitation: You can’t immediately invoke it.

Function Expression

The function expression is more flexible, e.g.:

// Executed immediately
(function() {
   alert("I am not a function statement.");
}());

  

Parentheses are required to nudge function out of statement position (can’t immediately invoke), and into expression position (can immediately invoke). Crockford recommends grouping the entire invocation inside parentheses for clarity - what’s important here is the product of the invoked function - otherwise, Crockford argues, “you’ve got these things hanging outside of it looking like dog balls.”

WINNER: Function Expression.

FINAL SCORE: Function Expression Wins 3 - 0

CONCLUSION - I HEART A GOOD MANUAL

It turns out the function statement came first; the function expression was added to JavaScript later. The result is two very similar ways of defining JavaScript functions. Logically, the addition was intended to improve the language, and, in this case, it would seem this end was achieved.

If you haven’t already seen it, here’s a particularly entertaining speech (2011) Crockford gave on his approach to JavaScript:

时间: 2024-10-12 16:42:03

Function Smackdown: Function Statement vs. Function Expression的相关文章

syntax error: non-declaration statement outside function body

在函数外部使用形如:name:="mark"这样语句会出现 syntax error: non-declaration statement outside function body package main import "fmt" var age uint8 // ok var age1 uint8 = 18 // ok var age2 = 18 // ok age3 := 18 // error // 出错的原因在于 age3 := 18实际上是两条语句 v

Adding New Functions to MySQL(User-Defined Function Interface UDF、Native Function)

catalog 1. How to Add New Functions to MySQL 2. Features of the User-Defined Function Interface 3. User-Defined Function 4. UDF Argument Processing 5. UDF Return Values and Error Handling 6. UDF Compiling and Installing 7. Adding a New Native Functio

1、function aa(){}和 var aa=function(){}的区别:

例如: alert(sum(10,10)); function sum(num1,num2){ return num1+num2; }//正常执行 备注:正常执行的那个,在代码开始执行之前,解析器就通过一个名为函数声明提升的过程,读取并将函数声明添加到执行环境中,对代码求值时,javaScript引擎在第一遍会声明函数并将它们放到源代码数的顶部 alert(sum(10,10)); var sum=function(num1,num2){ return num1+num2; }//报错 1.fu

在JS中关于堆与栈的认识function abc(a){ a=100; } function abc2(arr){ arr[0]=0; }

平常我们的印象中堆与栈就是两种数据结构,栈就是先进后出:堆就是先进先出.下面我就常见的例子做分析: main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main() { int b; 栈 char s[] = "abc"; 栈 char *p2; 栈 char *p3 = "123456"; 123456\0在常量区,p3在栈上. static int c =0: 全局(静态)初始化区 p1 = (char *)malloc(1

simulink error:Error in default port dimensions function of S-function ‘XXXXXXXXXXX’. This function does not fully set the dimensions of output port 2.

错误提示: Error in default port dimensions function of S-function 'XXXXXXXXXXX'. This function does not fully set the dimensions of output port 2. 问题描述:将m函数添加到simulink中的MATLAB function中后,运行后显示'XXXXXXXXXXXXX',这个模块的端口配置错误. 解决方法:双击MATLAB function模块,进入编程界面(如

JavaScript中Function Declaration与Function Expression 或者说 function fn(){}和var fn=function(){} 的区别

JavaScript是一种解释型语言,函数声明会在JavaScript代码加载后.执行前被解释,而函数表达式只有在执行到这一行代码时才会被解释. 在JS中有两种定义函数的方式, 1是:var aaa=function(){...} 2是:function aaa(){...} var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用. function方式定义函数可以先调用,后声明. var func=function 和 function func()在意义上没有任何不同,但其

Expected an assignment or function call and instead saw an expression no-unused-expressions

中文翻译为:期望一个赋值或函数调用,却看到一个表达式未使用表达式 我的问题 赋值 错写成了 等式: 原文地址:https://www.cnblogs.com/qiangwu66/p/10654063.html

jQuery中$(function(){})与(function($){})(jQuery)、$(document).ready(function(){})等的区别详细讲解

1.(function($) {…})(jQuery); 在(function($) {…})(jQuery)在内部定义的函数和变量只能在此范围内有效. 形成是否函数函数.私有变量的概念.比如: var i=3; function init(){ alert("外层init:"+i); } (function($) { var i=2; function init(){ alert("内层init:"+i); } init(); })(jQuery); init()

关于 function a(){} 和 var a=function(){}

例: a(); b(); function a(){console.log(111);} var b = function(){console.log(222);} 运行发现 111.b is not a function; 这是因为function a(){}在代码执行前进行了预编译. 什么是js的预编译? js会把var和function这两个声明关键字提前解释一下,而变量的赋值是在代码执行时完成. 即:var b = function(){}在预编译阶段,相当于 var b ,而在执行的时