以下函数调用如何在Javascript中工作

时间:2011-07-02 00:59:45

标签: javascript functional-programming scope

我一直在玩与this really cool文章相关联的代码。

在文章代码中,为变量分配了如下函数:

var messageFactory = (function() {
    var that = {},
        $chatMessage = $('<p></p>').
          addClass('chat message'),
        $nick = $('<span></span>').
          addClass('nick'),
        $systemMessage = $('<p></p>').
          addClass('system message');

    var chat = function(message) {
      var $filledNick = $nick.clone().
            text(message.nick + ':');
      return $chatMessage.clone().
        append($filledNick).
        append(message.text);
    };

    var system = function(message) {
      return $systemMessage.clone().text(message.text);
    };

    that.chat = chat;
    that.system = system;

    return that;
  })();

后面的子函数被调用如下,

messageFactory.system({ text: 'You changed your nick to ' + nick + '.'})

messageFactory.chat({ nick: 'me', text: message })

这些电话发生了什么?具体来说,似乎var messageFactory的工作方式类似于C#等语言中的类定义,而且我缺少与通过对象传递值的范围相关的机制{text:'...'...}

非常感谢!

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

第一个也是最重要的事情是最后一行。具体而言,()之前的;。这样做是立即执行第1行的匿名函数。这一点很重要,因为messageFactory不包含匿名函数,而是包含从它返回的任何函数。为了更好地理解这一点,我将举一个例子......

var x = (function(){ return "Hello!"; })();
// x will contain "Hello!", not the function.

要记住的第二件事是Javascript中的对象将维护对它们所创建的闭包的引用。因此,如果您立即执行我们上面所做的函数,那将形成一个闭包和对象在该闭包中创建的即使在函数执行完毕后也将保持对它的引用。另一个例子......

var sayHi = (function(){ 
    var salutation = "Hello";
    return function(name) {
       return salutation + ", " + name + ".";
    }
})();

再次注意我们有一个立即执行的匿名函数。因此变量sayHi将不包含外部匿名函数,而是它的返回值。因此sayHi实际上会包含function(name){ return salutation + ", " + name + ".";}。您会注意到我们没有传递salutation,但我们仍然可以访问它,因为它是创建此函数的closure的一部分。

理解提供的代码的最后一点是,在Javascript中,{}是一个Object文字。它基本上等同于new Object()。这些对象可以具有与C#对象相同的属性和方法,这是.text来自您所引用的对象。

在第2行,代码正在创建一个Object文字:var that = {}。下一个var创建是var chat = function(message){....,其中创建了一个函数,该函数接受message参数并对其执行一些操作。在代码末尾,chat函数随后被分配到chat的{​​{1}}属性,然后返回thatthat和{{1 }}

所有这一切的要点是that.chat = chat不包含它似乎被赋予的功能,而是包含该功能的return that。在这种情况下,该返回实际上是messageFactory对象,它具有returnthat两个属性。这些属性实际上指向创建chat的同一个闭包内的systemchat变量,这使得这一切都能正常工作。

最后一段很简单....当你致电system Joe that时,你实际上是将messageFactory.chat({ text: 'something', nick:作为参数传递给})内部的Object函数关闭。然后它引用对象的chatnick属性以返回其结果。

希望有所帮助。我不确定我是否解释得很好,但这就是它在我脑海中的作用。