Js函数加括号、不加括号

Js函数加括号、不加括号

 

(function a(){}) (命名函数表达式)会返回这个函数(不会执行),但是在括号外面无法调用该函数,需要一个变量接收这个函数,var fun = (function a(){}),一般这个用在递归上,比如
var fact = (function f(num){  
      if(num === 1 )
          return 1;
      else 
          return num * f(num - 1);
      })
 

function a(){}       【函数声明】返回undefined(不会执行),仅仅是函数声明(声明提前)

var res = function a(){}()    【函数表达式】,立即执行该函数,必须使用一个变量接收返回值,否则报错。

(function a(){})()      【函数表达式】,立即执行该函数,不必须使用变量接收

     示例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
        //1.函数声明,不会执行。
        function a() {
            alert("函数a");
        }
 
        //2.函数表达式,立即执行该函数,必须使用一个变量接收返回值,否则报错。
        var res = function b() {
            alert("函数b");;
        }();
 
        //3.函数表达式,立即执行该函数,不必须使用变量接收。
        (function c() {
            alert("函数c")
        })();
    </script>
</head>
<body>
</body>
</html>

 

==================================

函数只要是要调用它进行执行的,都必须加括号。此时,函数()实际上等于函数的返回值。当然,有些没有返回值,但已经执行了函数体内的行为,这个是根本,就是说,只要加括号的,就代表将会执行函数体代码。
 

不加括号的,都是把函数名称作为函数的指针,用于传参,此时不是得到函数的结果,因为不会运行函数体代码。它只是传递了函数体所在的地址位置,在需要的时候好找到函数体去执行。

函数调用都得加()
传说中的
(function() {

})();
无非就是

绿括号 -> 函数定义
蓝括号 -> 函数执行
红括号 -> 把整个函数定义包起来,定义完了再执行,看得更直观

================================

 

在JavaScript经常会看到这样的代码 

( function(  $ ){
        $( ‘body‘ ).css( { ‘background-color‘: ‘#ccc‘ } );
} )( jQuery );

这里的一个JavaScript函数被一个括号括了起来, 然后后面紧跟着一个括号,这种奇葩的写法在其它如Java、VB、c#、c++、php等流行编程语言中根本见不到。这种写法乍一看是JavaScript特意增加的新奇特性, 其实并不是。 在我们编写任何程序时,时时刻刻在用到与上面代码类似的特性, 只不过是以另一种面貌展示而已。 说穿了这其它只是括号的运用而已。

在小学数据就学习了括号在加减乘除四则运算中可以控制优先级。 (1+1)*3这是一个最简单的表达式了, 在编程语言中逻辑运算过程是这样的,先计算被括号括起来的(1+1)部份, 返回结果2, 然后再与后面的3相乘, 得出结果为6, 在这里括号有优先运算并返回结果的功能。把这个规则套用于上面的JavaScript代码

( function( $ ){
     $( ‘body‘ ).css( { ‘background-color‘: ‘#ccc‘ } );
} )

这段代码其实也是一个括号运算, 只不过这个括号返回的并不是四则运算中计算的结果, 而是一个函数。 可以把这个括号运算看成是一个函数执行, 返回的结果可以是基本类型、对象、函数等等。这里还有第二个括号, 第二个括号其实是一个函数调用。在大多数编程语言中, 调用函数的方法都是在函数名后面加上一个括号, 如果有参数, 可以把参数写在括号里面,JavaScript也不例外。所以上面示例代码的整个执行过程是第一个括号返回一个函数, 第二个括号调用第一个括号返回的函数, 整个过程其实就是一个函数调用, 只不过穿上一身奇怪的衣服变的不容易认出来而已。示例的代码其实完全可以被下面的代码替代

function exec( $ ) {
      $( ‘body‘ ).css( { ‘background-color‘: ‘#ccc‘ } );
};
exec( jQuery );

这段代码比之前的代码易理解很多, 但是两者得到的结果一点区别都没有, 只是写法不同而已。不过这段代码多出来一个函数名, 这个函数是一个全局函数,有引起命名冲突的危险, 这可能就是别人更愿意用使用括号的写法而不愿意用这种写法的原因吧。不过还有其它的方法可以替代使用括号的写法, 而且易理解性也更强一些, 并且也没有全局命名冲突的问题。下面是两种替代的写法

void function( $ ){
    $( ‘body‘ ).css( { ‘background-color‘: ‘#ccc‘ } );
}( jQuery );

!function( $ ){
     $( ‘body‘ ).css( { ‘background-color‘: ‘#ccc‘ } );
}( jQuery );

这四段示例代码中, 有三个使用的是匿名函数, 一个使用具名函数, 它们之间完全可以互相替代, 并且效果一样, 只是使用具名函数的代码容易引起命名冲突。

-------------分割线-----------------------------------------------------------------------------------------------

上面讲的是被括号括起来的函数的基本运行原理, 但为什么要选择这么做呢? 这么做有什么好处?  这之中涉及到软件工程的信息隐藏机制。在现代流行的面向对象编程语言中, 有类的概念, 类的成员有各种不同的访问修饰public、protected、private, 而在JavaScript中却没有这些, 但是这些特性却可以通过function模拟出来, 以达到类似的功效。在JavaScript中function有其它语言中class的功效。以下面这段代码为例

( function() {
    var person = [];
     
    function setName() {
       person.push( "name: Sola Aoi" );
    }
   function setAge() {
        person.push( "age:30" );
    }
   function setGender() {
        person.push( "gender:female" );
    }
    window[ ‘printPersonInfo‘ ] = function() {
        setName();
        setGender();
        setAge();
        document.write( person.join( "<br/>" ) );
    }
})( );

printPersonInfo();

这段代码就起到了很好的信息隐藏作用, 在代码中有一个变量和四个函数, 其中对外公开的就是一个printPersonInfo函数, 其它的几个都被隐藏在括号之中的函数里面。 所以在外面写代码只需要关注命名会不会和printPersonInfo函数冲突, 而不必去管其它三个, 这就相当于代码之中的person、setName、setAge、setGender都是private的, 而只有printPersonInfo是public的。还有一个好处, 你在改动代码之时, 可以任意修改 person、setName、setAge、setGender, 不用担心改动它们会影响到其它地方, 因为它们的作用都被限制在固定的作用域里面了, 只在那一块代码的作用域里被调用, 而不涉及到其它地方。 当然printPersonInfo不可以随意改动, 因为它被设置为对外公开, 在其它任意未知的地方都有可能被调用, 所以不能随意改动。 这种写法在这里效果已经很明显了, 把改动所受的影响从五个减少到了一个, 代码的易维护性大大的提高了。下面是一个Visual Basic版本实现, 实现的效果相同。

Module Module1
    Class Person
        Private Shared person As List(Of String) = New List(Of String)
        Private Shared Sub SetName()
            person.Add("name: Sola Aoi")
        End Sub
        Private Shared Sub SetGender()
            person.Add("age:30")
        End Sub
        Private Shared Sub SetAge()
            person.Add("gender:female")
        End Sub
        Public Shared Sub PrintPersonInfo()
            SetName()
            SetGender()
            SetAge()
            Console.Write(String.Join(vbCrLf, person.ToArray()))
        End Sub
    End Class
    Sub Main()
        Person.PrintPersonInfo()
    End Sub
End Module

原文来自:http://chhblog.com/article/291.html

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值