1

このコードでは

if (direction === 'up') {
    for (key in elements) {
        if (elements.hasOwnProperty(key)) {
            elements[key].style.opacity = statics.elapsed / max_time;
        }
    }
} else if (direction === 'down') {
    for (key in elements) {
        if (elements.hasOwnProperty(key)) {
            elements[key].style.opacity = (max_time - statics.elapsed) / max_time;
        }
    }
}

この一般的なイディオムを抽象化したい:

for (key in elements) {
    if (elements.hasOwnProperty(key)) {
        // function using elements[key] and outside parameters
    }
}

だから私は簡単に書くことができました

manyElements(element, function () {
});

関数プロトタイプを出発点としてどのように記述しますか。私の推測ではそうでしょう。

function manyElements (elements, the_function) {
    for (key in elements) {
        if (elements.hasOwnProperty(key)) {
            the_function();
        }
    }
}

しかし、外部パラメータにアクセスする必要があります。これらを渡す最良の方法は何ですか? このコードを抽象化することは、一般的に良い考えですか?

汎用関数を作成するという目的を個別に無効にするために、各パラメーターを渡す必要があるようです。

相互関係を除いて、外部ライブラリを使用したくありません。ここでの答えはlodashの実装です:

スニペット 1

  function forEach(collection, callback, thisArg) {
    if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
      var index = -1,
          length = collection.length;

      while (++index < length) {
        if (callback(collection[index], index, collection) === false) {
          break;
        }
      }
    } else {
      each(collection, callback, thisArg);
    }
    return collection;
  }

スニペット 2

var each = createIterator(eachIteratorOptions); 

スニペット 3

  function createIterator() {
    var data = {
      'arrayLoop': '',
      'bottom': '',
      'hasDontEnumBug': hasDontEnumBug,
      'isKeysFast': isKeysFast,
      'objectLoop': '',
      'nonEnumArgs': nonEnumArgs,
      'noCharByIndex': noCharByIndex,
      'shadowed': shadowed,
      'top': '',
      'useHas': true
    };

    // merge options into a template data object
    for (var object, index = 0; object = arguments[index]; index++) {
      for (var key in object) {
        data[key] = object[key];
      }
    }
    var args = data.args;
    data.firstArg = /^[^,]+/.exec(args)[0];

    // create the function factory
    var factory = Function(
        'createCallback, hasOwnProperty, isArguments, isString, objectTypes, ' +
        'nativeKeys, propertyIsEnumerable',
      'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}'
    );
    // return the compiled function
    return factory(
      createCallback, hasOwnProperty, isArguments, isString, objectTypes,
      nativeKeys, propertyIsEnumerable
    );
  }
4

2 に答える 2

2

最初は、lodash や underscore など、すでにそれを行っているライブラリがいくつかあります。http://lodash.com/docs#forEach関数を確認してください。

次に、 Object.keys(elements).forEach(function (key) { ... }) を使用してコードをショートカットできます。

そして 3 番目に、JavaScript 関数について読む必要があるかもしれません。それらは、パラメーターとして他の関数に渡されてから呼び出されます。このような:

function do(something) {
 ...
 something(item);
 ...
}
do(function (arg) { console.log(arg); });
于 2013-02-04T02:01:38.893 に答える
1

コードでこれを数回行う場合、それを抽象化しても問題はありません。あなたもほとんど答えを持っています: 必要なパラメータを に渡した関数に戻すだけですmanyElements. いくつかの場所でキーが必要になる可能性があるため(たとえば、割り当てを別のものに変更する場合)、キーと値の両方を渡すことにします。

function manyElements (elements, the_function) {
    for (key in elements) {
        if (elements.hasOwnProperty(key)) {
            the_function(key, elements[key]);
        }
    }
}

使用法は次のようになります。

if (direction === 'up') {
    manyElements(elements, function (key, value) {
        value.style.opacity = statics.elapsed / max_time;
    });
} else if (direction === 'down') {
    manyElements(elements, function (key, value) {
        value.style.opacity = (max_time - statics.elapsed) / max_time;
    });
}

ただし、その名前は関数の機能を実際に説明していないため、関数を manyElements とは呼びません。のようなものforEachPropertyは、より自己文書化されている可能性があります。

于 2013-02-04T02:15:48.640 に答える