Underscore.js 1.7の使い方 Functions編

Underscore.js 1.7の使い方 Functions編

bind

オブジェクトに関数をバインドする

var r = document.getElementById("r");
var func = function(greeting) {
  r.innerHTML =  greeting + this.name
};
func = _.bind(func, {name: 'sato'}, 'Hello ');
func();
// => Hello sato

サンプル

bindAll

指定したメソッドをバインドする

var r = document.getElementById("r");
var buttonView = {
  label  : 'test',
  onClick: function() {
    r.innerHTML += this.label + ' click! ';
  },
  onMouseover: function() {
    r.innerHTML += this.label + ' mousever! ';
  }
};
_.bindAll(buttonView, 'onClick', 'onMouseover');
$("#b").bind('click', buttonView.onClick);
$("#b").bind('mouseover', buttonView.onMouseover);

サンプル

partial

引数を追加して関数に追加

var r = document.getElementById("r");
var add = function(a, b) {
  return a + b;
};
add5 = _.partial(add, 5);
r.innerHTML = add5(10);

サンプル

memoize

関数の計算結果をキャッシュ

// フィボナッチ数の関数作成
var r = document.getElementById("r");
var fibonacci = _.memoize(function(n) {
  return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
});
r.innerHTML = fibonacci(10);
// => 55

サンプル

delay

関数を指定したミリ秒後に実行

var r = document.getElementById("r");
var log = _.bind(console.log, console);
_.delay(log, 3000, 'hoge');
// => hoge

サンプル

defer

setTimeoutの0ミリ秒指定と同じ

var r = document.getElementById("r");
_.defer(function() {
  r.innerHTML = 'deferred';
});
// => deferred
// setTimeoutの0ミリ指定と同じ
// setTimeout(function() {
//   r.innerHTML = 'deferred';
// }, 0);

サンプル

throttle

関数を指定したミリ秒毎に実行(処理の間引き)

// 1秒に1回処理
var throttled = _.throttle(updatePosition, 1000);
function updatePosition() {
  $("#r").text($(window).scrollTop() + 'px');
}
function updatePosition2() {
  $("#r2").text($(window).scrollTop() + 'px');
}
// 左下 スクロール時に1秒に1回処理
// 右下 スクロール時に常に処理
$(window).scroll(throttled);
$(window).scroll(updatePosition2);

サンプル

debounce

関数を指定したミリ秒後に実行

// ブラウザのウィンドウをリサイズすると1秒後に処理を実行
var alertResize = _.debounce(alertResizeFunc, 1000);
function alertResizeFunc() {
  $("#r").html(
    'ウィンドウをリサイズしました。<br>' +
    '幅は' + $(window).width() + 'pxです。'
  )
}
$(window).resize(alertResize);

サンプル

once

関数を最初の1回のみ実行

var r = document.getElementById("r");
var init = _.once(addText);
function addText() {
  r.innerHTML += 'Hello world!';
}
// 3回分記述しても実行されるのは最初の1回のみ
init();
init();
init();

サンプル

after

指定した回数目から関数を実行できるようになる

var r = document.getElementById("r");
var i = 0;
var afterFunc = _.after(3, render);
function render () {
  i++;
  r.innerHTML += i + '回目<br>';
}
afterFunc();
r.innerHTML += '<hr>';
afterFunc();
r.innerHTML += '<hr>';
// 3つ目のafterFunc()から処理が実行される
afterFunc();
r.innerHTML += '<hr>';
afterFunc();
r.innerHTML += '<hr>';
afterFunc();

サンプル

before

指定した回数目から関数が実行されなくなる

var r = document.getElementById("r");
var i = 0;
var beforeFunc = _.before(3, render);
function render () {
  i++;
  r.innerHTML += i + '回目<br>';
}
beforeFunc();
r.innerHTML += '<hr>';
beforeFunc();
r.innerHTML += '<hr>';
// 3つ目のbeforeFunc()から処理が実行されない
beforeFunc();
r.innerHTML += '<hr>';
beforeFunc();
r.innerHTML += '<hr>';
beforeFunc();

サンプル

wrap

関数を覆って前後に処理を追加できるようにする

var r = document.getElementById("r");
var hello = function(name) { return 'hello ' + name; };
hello = _.wrap(hello, function(func) {
  return "before " + func("suzuki") + " after";
});
r.innerHTML = hello();
// => before hello suzuki after

サンプル

negate

否定の結果を返す

var r = document.getElementById("r");
var isFalse = _.negate(Boolean);
var isNotNumber = _.negate(Number);
r.innerHTML = _.find([-2, -1, 0, 1, 2], isFalse);
// => 0
r2.innerHTML = _.find([1, 2, 'three', 4], isNotNumber);
// => three

サンプル

compose

複数の関数を組み合わせて返す

var r = document.getElementById("r");
var hello = function(name) { return 'Hello ' +  name; };
var world = function(str) { return str + ' world!'; };
var result = _.compose(hello, world);
r.innerHTML = result('sato');
// => Hello sato world!

サンプル

ほかのUnderscore.jsの記事