被括号括住的JavaScript函数

在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

时间: 2025-01-04 22:30:46

被括号括住的JavaScript函数的相关文章

javascript 函数和作用域(六)

重点. 一.函数 函数是一块JavaScript代码,被定义一次,但可执行和调用多次.JS中的函数也是对象,所以JS函数可以像其他对象那样操作和传递,所以我们也常叫JS中的函数为函数对象. 注意: 函数的返回值,依赖于return语句. 一般的函数调用:如果没有return语句的话,默认会在所有代码执行完以后返回undefined. 如果是作为构造器,外部使用new去调用的话,如果没有return语句,或者return的是基本类型的话,默认会将this作为返回. 反之,如果return的是对象,

JavaScript 函数声明和变量声明

声明语句:声明语句是用来声明或定义标识符(变量和函数名)并给其赋值. 1:var 变量声明(5.3.1节): var语句用来声明一个或多个变量:var name_1 = [= value_1] [ ,..., name_n [= value_n]] var i; var j = 0; var x=1, y=2; var pi = 3.14, f = function(x) {return x*x}, k = f(x); 2:遗漏声明(3.9节) 读取一个没有声明的变量的值:JavaScript会

HTML 学习笔记 JavaScript (函数)

函数是由事件驱动的或者当他被调用时执行的可重复使用的代码块 实例 <!DOCTYPE html> <html> <head> <script> function myFunction() { alert("Hello World!"); } </script> </head> <body> <button onclick="myFunction()">点击这里</b

Javascript 函数及其执行环境和作用域

函数在javascript中可以说是一等公民,也是最有意思的事情,javascript函数其实也是一个对象,是Function类型的实例.因此声明一个函数首先可以使用 Function构造函数: var saySomething = new Function("something","console.log(something)"); saySomething("hello world!"); // 输出hello world! Function

Javascript 函数表达式

函数有两种模式:函数定义与函数表达式. 函数定义是在任何语言中都会遇见的,这里不再多说了. 函数表达式: 是作为表达式在代码中出现,当程序运行到此处时,才执行这部分的代码内容. 函数字面量组成部分: 第一部分,关键词 function    第二部分,函数名,但是可有可无.    第三部分,包含在括号内的参数,当然参数也是可有可无的,括号不能少.    第四部分,是一组包裹在大括号的语句块,也就是函数要执行的具体代码,可以为空. 例如 function () {} 这个写法符合上面4条规则,但却

深入浅出JavaScript函数 v 0.5

本文的观点是建立在<JavaScript权威指南 6th Ed> <JavaScript高级编程 3th Ed> <JavaScript精粹 2th Ed>之上, 笔者将尽所能将概念.原理叙述清楚,由于笔者水平有限,理解不当之处在所难免,请读者不吝交流. 目录 1 什么是函数? 2 函数就是对象! 3 函数字面量(函数表达式) 4 函数调用 4.1 方法调用模式 4.2 函数调用模式 4.3 构造器调用模式 4.4 间接调用模式 5 函数的参数与返回值 6 扩充类型的功

JavaScript权威设计--JavaScript函数(简要学习笔记十二)

1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. 如: function my(){ } my(); //别忘记调用 这段代码定义了一个单独的全局变量:名叫"my"的函数. 我们还可以这么写,定义一个匿名函数: (function(){ //这里第一个左括号是必须的,如果不写,JavaScript解析器会将 //function解析成函

JavaScript 函数 学习 3(转)

JavaScript 函数 函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块; JavaScript 函数语法 函数就是包裹在花括号中的代码块,前面使用了关键词 function: 当调用该函数时,会执行函数内的代码. 可以在某事件发生时直接调用函数(比如当用户点击按钮时),并且可由 JavaScript 在任何位置进行调用. 调用带参数的函数 在调用函数时,您可以向其传递值,这些值被称为参数. 这些参数可以在函数中使用. 您可以发送任意多的参数,由逗号 (,) 分隔: 当您声明函数时

JavaScript 函数定义方法

JavaScript 函数定义方法. 函数声明 在之前的教程中,你已经了解了函数声明的语法 : function functionName(parameters) { 执行的代码 } 函数声明后不会立即执行,会在我们需要的时候调用到. function myFunction(a, b) { return a * b; } 分号是用来分隔可执行JavaScript语句. 由于函数声明不是一个可执行语句,所以不以分号结束. 函数表达式 JavaScript 函数可以通过一个表达式定义. 函数表达式可