Underscore.jsおさらい5(Objects)

keys _.keys(object)

keyの一覧が配列で返る。

_.keys({one: 1, two: 2, three: 3});
=> ["one", "two", "three"]


allKeys _.allKeys(object)

prototypeも含めて全キーが返る。

function Stooge(name) {
  this.name = name;
}
Stooge.prototype.silly = true;
_.allKeys(new Stooge("Moe"));
=> ["name", "silly"]


values _.values(object)

valueの一覧が配列で返る。key()と同様、prototypeは含まれない。

_.values({one: 1, two: 2, three: 3});
=> [1, 2, 3]


mapObject _.mapObject(object, iteratee, [context])

iteratee処理結果の新しいオブジェクトができる。
Collectionsのmapのオブジェクト版。

_.mapObject({start: 5, end: 12}, function(val, key) {
  return val + 5;
});
=> {start: 10, end: 17}


pairs _.pairs(object)

各(key, value)のセットを1配列とした配列に置き換える。

_.pairs({one: 1, two: 2, three: 3});
=> [["one", 1], ["two", 2], ["three", 3]]


invert _.invert(object)

keyとvalueを逆にしたオブジェクトを返す。valueが一意である必要がある。
もし一意でなくてもエラーにはならないけど、あえて使うこともない。

_.invert({Moe: "Moses", Larry: "Louis", Curly: "Jerome"});
=> {Moses: "Moe", Louis: "Larry", Jerome: "Curly"};


create _.create(prototype, props)

第一引数をprorotypeとして、第二引数を値に持った新オブジェクトを作る。

function Stooge(name, age) {
  this.name = name;
  this.age = age;
};
Stooge.prototype.silly = true;
Stooge.prototype.say = function(){console.log('I am ' + this.name)};
var stoo = new Stooge('aaa', 'bbb');
var moe = _.create(stoo, {name: "Moe", silly: false});
=> {name: "Moe", silly: false}

moe.say();
=> I am Moe


functions _.functions(object)

メソッド名一覧を返す。

function Stooge(name, age) {
  this.name = name;
  this.age = age;
};
Stooge.prototype.silly = true;
var stoo = new Stooge('aaa', 'bbb');
_.functions(stoo);
=> ["say"]


findKey _.findKey(object, predicate, [context])

ArraysのfindIndexのオブジェクト(ハッシュ配列)版。predicateに該当するkeyを返す。

var moe = {name: "Moe", silly: false};
_.findKey(moe, function(value, key, obj) { return value == "Moe"; });
=> "name"
_.findKey(moe, function(value, key, obj) { return (key == "silly") && (value == "Moe"); });
=> undefined


extend _.extend(destination, *sources)

destinationを元に(継承して)、*sourcesで上書きしたオブジェクトを返す。

_.extend({name: 'moe'}, {age: 50});
=> {name: 'moe', age: 50}

_.extend({name: 'moe', age: 50}, {age: 40}, {silly: true});
=> {name: 'moe', age: 40, silly: true}


extendOwn _.extendOwn(destination, *sources)

extendとほぼ同じ。違いは*sourcesのprorotypeまで見に行くかどうか。
extendはprototypeまで見に行く、extendは見に行かない(ownまで)。

function Stooge(name) {
  this.name = name;
}
Stooge.prototype.silly = true;
_.extend({name: 'moe'}, new Stooge('hoge'));
=> {name: 'hoge', silly: true}
_.extendOwn({name: 'moe'}, new Stooge('hoge'));
=> {name: 'hoge'}


pick _.pick(object, *keys)

指定したkeyだけを持つオブジェクトを返す。keyにfunctionで条件指定も可能。

_.pick({name: 'moe', age: 50, userid: 'moe1'}, 'name', 'age');
=> {name: 'moe', age: 50}
_.pick({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) {
  return _.isNumber(value);
});
=> {age: 50}


omit _.omit(object, *keys)

pickの逆版。条件に合致しないキーだけを持つオブジェクトを返す。

_.omit({name: 'moe', age: 50, userid: 'moe1'}, 'userid');
=> {name: 'moe', age: 50}
_.omit({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) {
  return _.isNumber(value);
});
=> {name: 'moe', userid: 'moe1'}


defaults _.defaults(object, *defaults)

extendの先勝ちみたいな。defaultsにあるkeyがobject上でundefinedの場合に、defaults値を設定する。
object上にあれば(≠undefined)、objectの値がそのまま保持される。

var iceCream = {flavor: "chocolate"};
_.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});
=> {flavor: "chocolate", sprinkles: "lots"}


clone _.clone(object)

シャローコピー。

var obj = {age: 20};
_.clone({name: 'moe', obj: obj});
=> {name: 'moe', obj:{age: 20}};
obj.age = 30;
=> {name: 'moe', obj:{age: 30}};


tap _.tap(object, interceptor)

chainで処理を繋げている時に、途中の状態を表示するという使い方をする。
(何でchainingじゃなくてObjects扱いなんだろう?)

_.chain([1,2,3,200])
  .filter(function(num) { return num % 2 == 0; })
  .tap(alert)
  .map(function(num) { return num * num })
  .value();
=> // [2, 200] (alerted)
=> [4, 40000]


has _.has(object, key)

keyがあるかどうかチェック。 hasOwnProperty()はobjectがnullだとエラーになるが、こちらはfalseを返してくれる。

_.has({a: 1, b: 2, c: 3}, "b");
=> true
_.has(null, "b");
=> false


property _.property(key)

obj[ key ]を返す関数を作る。使いドコロが、、、chainingで使う?

var stooge = {name: 'moe'};
'moe' === _.property('name')(stooge);
=> true


propertyOf _.propertyOf(object)

object[ key ]を返す関数を作る。objectを先に渡すところがpropertyとの違い。

var stooge = {name: 'moe'};
_.propertyOf(stooge)('name');
=> 'moe'


matcher _.matcher(attrs)

条件に合致する処理を行う関数を返す。
key == key && value == valueな判定の関数を作ってくれるので、filterの条件をさくっと作れる。

var ready = _.matcher({selected: true, visible: true});
var readyToGoList = _.filter(list, ready);


isEqual _.isEqual(object, other)

objectの各プロパティが同じならtrueを返す。
object == other がfalseでも中の値が完全同一ならtrueになる。

var stooge = {name: 'moe', luckyNumbers: [13, 27, 34]};
var clone  = {name: 'moe', luckyNumbers: [13, 27, 34]};
stooge == clone;
=> false
_.isEqual(stooge, clone);
=> true


isMatch _.isMatch(object, properties)

containsのハッシュ配列版みたいな。objectにpropertiesが含まれていればtrue。

var stooge = {name: 'moe', age: 32};
_.isMatch(stooge, {age: 32});
=> true


以下は判定系で名前から想像つくので簡単に。

isEmpty _.isEmpty(object)

空判定。値がないオブジェクト({})や、配列や文字列などのlengthを持つものでlength=0ならtrue。

isElement _.isElement(object)

DOMエレメント判定。

isArray _.isArray(object)

配列判定。

isObject _.isObject(value)

オブジェクト判定。

isArguments _.isArguments(object)

引数オブジェクト判定。

isFunction _.isFunction(object)

関数判定。

isString _.isString(object)

文字列判定。

isNumber _.isNumber(object)

数値判定。

isFinite _.isFinite(object)

無限大判定。

isBoolean _.isBoolean(object)

真偽値判定。

isDate _.isDate(object)

日時オブジェクト判定。

isRegExp _.isRegExp(object)

正規表現判定。

isError _.isError(object)

エラー判定。

isNaN _.isNaN(object)

非数判定。純粋にNaNかどうか判断する。undefinedはfalseになる。

isNull _.isNull(object)

null判定。undefinedはfalseになる。

isUndefined _.isUndefined(value)

undefined判定。nullはfalseになる。


Objectは数は多いが感覚的に理解できるものが多いので分かりやすい。