• JavaScript中的自调用函数


    自调用函数

    自调用函数(self-invoking funciton)就是函数定义完之后会立即运行的函数. 最常见的写法是:

    (function() {
      // function body...
    }());
    // or
    (function() {
      // function body...
    })();
    

    自调用函数的另一种写法

    不过最近看某个库的源代码(暂时忘了是哪个了=,.=)时发现有如下写法:

    +function() {
      // function body
    }();
    

    感到神奇, 于是SO了一下, 原来这是另一种自调用函数的写法.

    +号使得js解释器认为它现在在处理的是一个表达式, 而非函数定义. 如果不写这个+号, 解释器会按照函数定义去处理, 并认为后面的()是语法错误.

    其实除了+号, -, !, ~以及其他一元操作符都可以产生相同的效果.

    与要在用()把函数包起来的常用写法相比, 这种写法的好处(也许)就是只要在前面加个+就行了, 更省事儿. 当然, 最后的();是一定不能少的.

    需要注意的问题

    主要注意的是, 一定不能省略自调用函数前面赋值语句的;.

    如果自调用函数前面是函数定义, 一切正常:

    function x() { console.log(1); } +function () { console.log(2); }();
    // 2
    

    但是如果它前面是个赋值语句, 你的代码非常容易出bug, 即使是用()包裹自调用函数也不行.

    var s = {}; s.a = function() { console.log(1); } + function() { s.a(); }();
    // Uncaught TypeError: s.a is not a function(…)
    var s = {}; s.a = function() { console.log(1); } (function() { s.a(); }());
    // Uncaught TypeError: s.a is not a function(…)
    var a = function() { console.log(1); } + function() { console.log(2); }();
    // 2
    // a is “function () { console.log(1); }undefined”
    var a = function() { console.log(1); } (function() { console.log(2); }());
    // 2 1
    // a is `undefined`!!
    var a = function() { console.log(1); } (+ function() { console.log(2); }());
    // 2 1
    // a is `undefined`!!
    

    我以前曾经遇到这个bug, 但是并不知道发生了什么, 只是很奇怪为什么自调用函数前面的那个函数会自动执行... 后来我无奈用了下面这种弱鸡的形式

    function init() {
      // function body
    }
    init();
    

    正确的做法应该是:

    var x = function() {
      console.log(1);
    }; // <---------------- here! DO NOT omit this semicolon!
    + function() {
      console.log(2);
    }();
    

    我还听说有minify之前运行得好好的, minify之后就出bug, 也是因为少了;.

    综上, 在每句赋值语句后面加上;号是一个很重要的好习惯!

    自调用函数前面的;

    2016/4/14更新

    今天瞟了一眼platform.js的源代码, 看到最外层是

    ;(function() {
      // function body...
    }.call(this));
    

    SO了一下, 这是一种更加保险的方式.

    假设两个文件的内容分别是:

    // File A
    (function(){console.log(1);})()
    // File B
    (function(){console.log(2);})()
    

    那么这两个文件打包到一起就会报错

    (function(){console.log(1);})()(function(){console.log(2);})()
    // Uncaught TypeError: (intermediate value)(...) is not a function(…)
    

    当然, 这个错误也是由于两个文件中不好的代码习惯导致的--就是最后没有加;. 而在(function...前面写上;就可以100%确保自调用函数的正常执行.

    参考

    1. Does omitting semicolons affect performance in JavaScript?
    2. Why should I use a semicolon after every function in javascript?
  • 相关阅读:
    Parameter HTTP 参数基类
    XMLHttpRequest对象 转载来源于:http://dev.yesky.com
    35 岁前程序员要规划好的四件事
    java 初学之二
    从零开始学wordpress 之四
    Adobe flash cs5 的Java运行时环境初始化错误 完美解决方法
    从零开始学wordpress 之三
    java 初学 之一
    java 初学之三 多态和抽象类
    简单的js优化
  • 原文地址:https://www.cnblogs.com/7z7chn/p/5370414.html
Copyright © 2020-2023  润新知