javascript 函数调用

在 javascript 中,每一个函数在被调用的时候都会创建一个执行上下文,在该函数内部定义的变量和函数只能在该函数内部被使用,而正是因为这个上下文,使得我们在调用函数的时候能创建一些私有变量。

  • 先声明后调用

    // 声明:

    var foo = function(){ /* code */ };

    // 调用:

    foo();

  • 如果想不声明直接调用

    function(){ /* code */ }();

    // 报错:SyntaxError: Unexpected token (

    // 执行到第一个左括号'('时报错,因为函数函数应该有函数名而这里没有

  • 加上函数名再调用

    function foo(){ /* code */ }();

    // 报错:SyntaxError: Unexpected token )

    // 执行到倒数第一个右括号')'时报错

    // 因为()是提高优先级的分组操作符,分组操作符内的表达式不能为空

使用立即执行函数(IIFE)

// 最常用的两种写法
(function(){ /* code */ }()); // 老道推荐写法
(function(){ /* code */ })(); // 当然这种也可以 // 括号和JS的一些操作符(如 = && || ,等)可以在函数表达式和函数声明上消除歧义
// 如下代码中,解析器已经知道一个是表达式了,于是也会把另一个默认为表达式
// 但是两者交换则会报错
var i = function(){ return 10; }();
true && function(){ /* code */ }();
0, function(){ /* code */ }(); // 如果你不怕代码晦涩难读,也可以选择一元运算符
!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }(); // 你也可以这样
new function(){ /* code */ }
new function(){ /* code */ }() // 带参数

《立即执行函数》还是《自执行函数》

IIFE 的称谓在现在似乎已经得到了广泛推广(不知道是不是原文作者的功劳?),而原文写于 10 年,似乎当时流行的称呼是自执行函数(Self-executing anonymous function),接下去作者开始为了说明立即执行函数的称呼好于自执行函数的称呼开始据理力争,有点咬文嚼字,不过也蛮有意思的,我们来看看作者说了些什么。

// 这是一个自执行函数,函数内部执行的是自己,递归调用
function foo() { foo(); } // 这是一个自执行匿名函数,因为它没有函数名
// 所以如果要递归调用自己的话必须用arguments.callee
var foo = function() { arguments.callee(); }; // 这可能也算是个自执行匿名函数,但仅仅是foo标志引用它自身
// 如果你将foo改变成其它的,你将得到一个used-to-self-execute匿名函数
var foo = function() { foo(); }; // 有些人叫它自执行匿名函数,尽管它没有执行自己,只是立即执行而已
(function(){ /* code */ }()); // 给函数表达式添加了标志名称,可以方便debug
// 但是一旦添加了标志名称,这个函数就不再是匿名的了
(function foo(){ /* code */ }()); // 立即执行函数也可以自执行,不过不常用罢了
(function(){ arguments.callee(); }());
(function foo(){ foo(); }());

我的理解是作者认为自执行函数是函数内部调用自己(递归调用),而立即执行函数就如字面意思,该函数立即执行即可。其实现在也不用去管它了,就叫 IIFE 好了。

最新文章

  1. cant create oci environment
  2. IP地址的组成
  3. Ubuntu 16.04 风扇特别响解决办法
  4. eclipse开发环境搭建
  5. [BZOJ1299]巧克力棒(博弈论)
  6. Oracle rac集群环境中的特殊问题
  7. 三层交换机+二层交换机配置VLAN+DHCP
  8. java对于文件传输时---编码格式的一些设置方法
  9. uva 757
  10. 枚举类型的单例模式(java)
  11. 【设计模式 - 10】之外观模式(Facade)
  12. [转] Linux中gcc,g++常用编译选项
  13. 黑马程序员_Java面向对象_包
  14. 怎样获取自己的SSL证书
  15. every、some数组方法
  16. ABP框架系列之十三:(Authorization-授权)
  17. Ubuntu 14.04 LTS 下使用校园网客户端DrclientLinux
  18. CTSC&APIO2018游记
  19. fiddler工作原理和代理设置
  20. 猜生日 Java小游戏

热门文章

  1. vue项目报错1 Vue is a constructor and should be called with the `new` keyword && jquery.js?eedf:3850 Uncaught TypeError: this._init is not a function...
  2. iOS-NSLog发布时取消打印日志
  3. IIS下设置跨域访问问题--Access-Control-Allow-Origin 站点跨域请求的问题
  4. html-DOM了解
  5. 安装CRMEasy步骤
  6. node模块管理
  7. JDBC实现最简单的增删改查
  8. Python核心技术与实战——十四|Python中装饰器的使用
  9. Java并发编程实战 第16章 Java内存模型
  10. 2017年全国卷3的21题与2018年全国卷3的21题命题背景是同一个函数$y=\frac{2x}{\ln(x+1)}$(再次瞎谈)