【问题标题】:Function expression in JavaScript confusionJavaScript 混淆中的函数表达式
【发布时间】:2016-04-20 14:48:39
【问题描述】:

我正试图从另一位开发人员那里理解这段代码,但我缺乏 JavaScript 知识。这个函数应该把一个站点的标题菜单转换成一个移动样式的菜单。

我理解为什么 jQuery 以 $ 的形式传入。我不明白变量CPCU 是如何被传递回自身的,或者为什么它被作为CPCU || {} 传递回来。有人可以帮我了解CPCU 变量在这种情况下是如何工作的吗?

var CPCU = (function (_cpcu, $) {
  'use strict';

  /**
   * Mobile Menu
   */

  var mmenu = _cpcu.Menu.mobile = _cpcu.Menu.mobile || {};
  // Properties.
  mmenu.id = '#mobile-menu';
  mmenu.el = $('');
  mmenu.api = {};
  mmenu.button = '#header-content .menu.button';
  mmenu.aniClass = 'animate';
  mmenu.opts = {
    slidingSubmenus: false
  };
  mmenu.config = {
    classNames: {
      selected: 'active'
    }
  };
  // Methods.
  mmenu.init = function () {
    mmenu.el = $(mmenu.id);
    // Move the active class to from the A to the LI, must happen before mmenu init.
    $('#mobile-menu').find('a.active').parent('li').addClass('active');
    // Now we can init the menu. otherwise it doesn't pick up the active LI.
    mmenu.api = mmenu.el.mmenu(mmenu.opts, mmenu.config).data('mmenu');
    mmenu.button = $(mmenu.button);
    mmenu.button.data('lines', $('.line1,.line2,.line3'));
    mmenu.button.click(function () {
      mmenu.api.open();
    });
    mmenu.api.bind('open', function () {
      mmenu.button.data('lines').addClass(mmenu.aniClass);
    });
    mmenu.api.bind('close', function () {
      mmenu.button.data('lines').removeClass(mmenu.aniClass);
    });
  };
  // Set up doc ready.
  $(document).ready(function () {
    mmenu.init();
  });
  return _cpcu;
})(CPCU || {}, jQuery);

【问题讨论】:

标签: javascript jquery function function-expression


【解决方案1】:

它试图通过立即调用一个函数来扩展一个具有更多属性/功能的对象,传入一个要扩展的对象,并在扩展后再次返回同一个对象。

首先,获取CPCU || {},如果CPCU 已经定义,它将传递给函数。如果不是,CPCU 将是falsy,因此传入|| 的右侧,这是一个新的空对象。然后将其用作内部的_cpcu 参数,并分配额外的属性等。

使用这种方法,您可以将功能的不同部分分解为不同的区域,可能将某些变量保留为这些区域的私有变量,或者保存在不同的文件中以便于维护等。

我说 "attempting" 更进一步,因为这段代码实际上是错误的。如果 CPCU 在运行时确实未定义,并且传入 {},那么这一行:

var mmenu = _cpcu.Menu.mobile = _cpcu.Menu.mobile || {};

会出错,因为它无法访问未定义的Menu 属性的mobile 属性。因此,虽然开发人员使用了一种模式来分解代码的不同区域,但该部分实际上依赖于另一个部分(定义 Menu 属性)事先已运行,这使得整个 CPCU || {} 没有实际意义。

【讨论】:

  • 是的,这很好:使用预初始化“守卫”模式编写的代码实际上应该可以工作:)
【解决方案2】:

参数CPCU || {} 用于说明在您发布的代码顶部的var CPCU 声明之前,一些其他代码可能已经初始化CPCU。模式很常见。

因此,如果CPCU 没有 定义(可能是常见的情况,虽然我当然对你的软件了解不多),那么传递给匿名函数的值将是新的空对象 ({})。然而,如果CPCU 已经被定义和初始化,那么它的当前值将会被传递。

因此,假设在某个页面上有一个不同的脚本,在您发布的代码之前通过 <script> 标签导入,它会执行以下操作:

var CPCU = { debug: true };

然后当您发布的代码运行时,它会看到CPCU 已经有一个值。这样做通常是为了增加灵活性并考虑不可预见的可能性。

【讨论】:

  • 那么是否必须在其他地方调用此代码才能运行此函数?如果是这样,你知道那个函数调用会是什么样子吗?
  • @AnneLee 我不明白这个问题。您发布的代码是独立的,不需要“调用”。但是,正如 James Thorpe 在另一个答案中指出的那样,something 必须预先初始化该 CPCU 对象,否则此处发布的代码将在运行时引发异常。除了涉及符号 CPCU 之外,我不知道其他代码可能是什么样子。
  • 哦,我明白了……这很有道理。非常感谢!
猜你喜欢
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 2015-08-02
  • 2023-03-08
相关资源
最近更新 更多