先看一段jQuery源码中匿名函数自执行的例子:

  (function( window, undefined ) {
// jquery code
})(window);

另外一种常见的写法:

  +function( $ ) {
// jquery code
})(window.jQuery);

这两种写法该如何理解呢?第二种写法前面为何要加“+”号,不加会是什么结果呢?

  function( $ ) {
// jquery code
})(window.jQuery); // 报错: Uncaught SyntaxError: Unexpected token (

先理解一些概念性的东西

函数表达式(Function Expression)

  • 将函数定义为表达式语句(通常是变量赋值)的一部分
  • 通过 Function Expression 定义的函数可以是命名的,也可以是匿名的
  • Function Expression 不能以“function”开头,只用通过函数左侧的变量来调用
  a(); // 错误调用 Uncaught TypeError: a is not a function
var a = function(){
alert('Function expression');
}
a(); // 正确

函数声明(Function Declaration)

  • 可以定义命名的函数变量,而无需给变量赋值
  • 函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用
  • JS将function当作一个函数声明的开始,而函数声明后面不能跟圆括号直接进行调用
  a(); // 这里可以正确调用
function a(){
alert('Function declaration');
}
a(); // 这里可以正确调用

错误原因解析

  function( $ ) {
// jquery code
})(window.jQuery); // 报错: Uncaught SyntaxError: Unexpected token (
  • 当js编译器开始执行的时候,碰见function之后,看到它周围没有任何东西。于是就把function关键字解析成函数声明,而函数声明后面不能跟圆括号直接进行调用,因此导致后面运行出错了
  • 我们只需要用一个括号把这个匿名函数包裹起来,或者前面使用如-,~,!这种其它的一元操作符,目的是告诉解析器在这些特定操作符附近的是一个表达式,避免js编译器将function关键字解析成函数声明,然后代码就能够正常执行

参考

https://www.jianshu.com/p/82cb460af066

https://www.cnblogs.com/cndotabestdota/p/5664112.html

JS中的匿名函数自执行、函数声明与函数表达式的更多相关文章

  1. js中的匿名函数和匿名自执行函数

    1.匿名函数的常见场景 js中的匿名函数是一种很常见的函数类型,比较常见的场景:   <input type="button" value="点击" id ...

  2. js中var的有或无--重复声明和以后的声明

    js中var的有或无--重复声明和以后的声明 使用var语句多次声明一个变量不仅是合法的,而且也不会造成任何错误. 如果重复使用的一个声明有一个初始值,那么它担当的不过是一个赋值语句的角色. 如果重复 ...

  3. js中的匿名函数自执行

    随笔,java中因为有修饰符的存在,那就有private类的存在,js不一样,没有修饰词一说,因此为了防止全局变量的污染,js中就出现了匿名函数,直接上code,看到的人可以自己体会: (functi ...

  4. JS中的匿名函数

    整理自:http://www.cnblogs.com/playerlife/archive/2012/10/17/2727683.html 一.什么是匿名函数? 在Javascript定义一个函数一般 ...

  5. node.js中的匿名函数, 回调函数和嵌套函数

    定义一个函数相信大家已经很熟悉了, 在javascript里的函数也是非常重要的, 使用率非常高, 有几种函数不是很好理解 一, 匿名函数 var remove = function(num1) { ...

  6. JS中的匿名函数、回调函数、匿名回调函数

    工欲善其事必先利其器 在学习JavaScript设计模式一书时,遇到了“匿名回调函数”这个概念,有点疑惑,查找了些资料重新看了下函数的相关知识点之后,对这个概念有了认识.九层之台,起于垒土.在熟悉这一 ...

  7. JS中setInterval、setTimeout不能传递带参数的函数的解决方案

    在JS中无论是setTimeout还是setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数,接下来为大家介绍具体的解决方法 在JS中无论是setTimeout还是s ...

  8. js中 var functionName = function() {} 和 function functionName() {} 两种函数声明的区别

    js中有两种声明函数的方法,分别为: var functionOne = function() { // Some code }; function functionTwo() { // Some c ...

  9. js中 var functionName = function() {} 和 function functionName() {} 两种函数声明的区别 (译)

    stackOverflow中看到了很久以前问的一个关于函数声明的问题,问题对函数剖析的特别深.这里翻译了一下组织成一篇小博文,加深一下对这两种声明方式的印象.虽是老调重弹,但是只要能帮助理解问题,不管 ...

随机推荐

  1. Binary Tree(生成二叉树)

    Description Background Binary trees are a common data structure in computer science. In this problem ...

  2. MathExamV2.0四则混合运算计算题生成器

    MathExamV2.0四则混合运算计算题生成器----211606360 丁培晖 211606343 杨宇潇 一.预估与实际 PSP2.1 Personal Software Process Sta ...

  3. HDU 5195 DZY Loves Topological Sorting 拓扑排序

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5195 bc(中文):http://bestcoder.hdu.edu.cn/contests ...

  4. DataTable转List<T>集合

    #region DataTable转List集合 +static IList<T> DataTableToList<T>(DataTable dt) where T : cla ...

  5. 复利计算程序单元测试(C语言)

    对我们和复利计算程序,写单元测试. 有哪些场景? 期待的返回值 写测试程序. 运行测试. 我的复利计算程序是用C语言写的,不懂使用C语言的测试工具,所以用C语言的运行结果来反映测试结果. 测试模块(场 ...

  6. 自己编写 Oracle 分页函数

    CREATE OR REPLACE PACKAGE PACK_PAGINATION AS PAGESIZE CONSTANT ; TYPE TYRECORD_EMP IS RECORD( EMPNO ...

  7. Java List部分截取,获得指定长度子集合

    subList方法用于获取列表中指定范围的子列表,该列表支持原列表所支持的所有可选操作.返回列表中指定范围的子列表. 语法 subList(int fromIndex, int toIndex) fr ...

  8. js & enter

    js & enter keycode function (e) { if (e.which === 13 || e.keyCode === 13) { //code to execute he ...

  9. 第114天:Ajax跨域请求解决方法(二)

    一.什么是跨域 我们先回顾一下域名地址的组成: http:// www . google : 8080 / script/jquery.js   http:// (协议号)       www  (子 ...

  10. RxSwift基本使用(一)

    备注:本文参考自田腾飞博文 [RxSwift入坑解读-你所需要知道的各种概念] (http://www.codertian.com/2016/11/27/RxSwift-ru-keng-ji-read ...