Javascript模式:(function(){}(function(){}))

时间:2014-07-26 14:57:37

标签: javascript design-patterns

如果这个问题非常简单,我提前道歉,我是JavaScript的初学者。

我发现了大量关于resembling pattern(模块模式)的信息,但除非我弄错了,否则这可能是不同的或扩展。以下是Mariusz Nowak的(精彩)domjs project的典型代码摘录:

renameReserved = (function (rename) {
    return function (scope) {
        Object.keys(scope).forEach(rename, scope);
    };
}(function (key) {
    if (contains.call(reserved, key)) {
        this['_' + key] = this[key];
        delete this[key];
    }
}));

我发现很难准确理解这里发生了什么,即使每个部分独立完成也很简单。非常感谢详细的帮助,或者链接到我可以了解更多相关信息。

2 个答案:

答案 0 :(得分:3)

这里涉及两个功能。第一个

function (rename) {
    return function (scope) {
        Object.keys(scope).forEach(rename, scope);
    };
}

另一个函数对象作为参数传递给该函数

function (key) {
    if (contains.call(reserved, key)) {
        this['_' + key] = this[key];
        delete this[key];
    }
}

由于我们使用参数执行第一个函数,(rename是保存函数对象的参数),它返回另一个函数,该函数保存由于closure属性而作为参数传递的函数。 / p>

答案 1 :(得分:1)

我将以不会改变发生的方式重写代码,但可能会让它更清晰一点:

function makeNameReplacer( rename ) {
    return function( scope ) {
        Object.keys(scope).forEach(rename, scope);
    }
}

function reservedWordRenamer( key ) {
    if (contains.call(reserved, key)) {
        this['_' + key] = this[key];
        delete this[key];
    }
}

renameReserved = makeNameReplacer( reservedWordRenamer );

所以第一个函数是创建函数的东西。创建的函数将名称替换策略应用于给定对象中的所有属性名称("范围")。

第二个功能是替换属性名称的策略。具体来说,它检查传入的属性名称(" key")是否在保留字集合中。如果是,则将其替换为以下划线为前缀的名称,并删除旧属性。

因此整体效果是" renameReserved"成为一个函数,一个将对象作为参数,并将删除属于保留字的属性名称。

您可以提出另一种策略,并制作另一项功能。例如,如果您想要属性名称都是大写的对象,则可以执行以下操作:

function upperCaseRenamer( key ) {
  var uckey = key.toUpperCase();
  if (key !== uckey) {
      this[uckey] = this[key];
      delete this[key];
  }
}

renameLowerCase = makeNameReplacer( upperCaseRenamer );