【Underscore.js】_.matcherを読んだ
jashkenas/underscoreの_.matcherを読んだ。
概要
_.matcher(attrs)
引数の「key : val」と同じものがあるかを判別する部分適用した関数を返す。
var matcher = _.matcher({age: 20, sex: "male"}); console.log(matcher({age: 20, sex: "male", country: "JP", name: "HOGA"})); // true
ソースコード
_.matcher = _.matches = function(attrs) { attrs = _.extendOwn({}, attrs); return function(obj) { return _.isMatch(obj, attrs); }; };
引数をshallow-copyして、それを_.isMatchに渡した関数を返している。
参考
【Underscore.js】_.omitを読んだ
jashkenas/underscoreの_.omitを読んだ。
概要
_.omit(object, *keys)
第1引数から第2引数以降で指定したkey値以外のkey値とその値で構成されたObjectを返す。
var x = _.omit( {age: 20, sex: "male", country: "JP", name: "HOGA"}, ['age', 'sex']); console.log(x); // {country: "JP", name: "HOGA"}
ソースコード
_.omit = function(obj, iteratee, context) { if (_.isFunction(iteratee)) { iteratee = _.negate(iteratee); } else { var keys = _.map(flatten(arguments, false, false, 1), String); iteratee = function(value, key) { return !_.contains(keys, key); }; } return _.pick(obj, iteratee, context); };
var keys = _.map(flatten(arguments, false, false, 1), String);
をしているのは、JSのobjectのkeyはString型であり、_.containsは===で比較するため。
参考
【Underscore.js】_.pickを読んだ
jashkenas/underscoreの_.pickを読んだ。
概要
_.pick(object, *keys)
第一引数から第2引数以降で指定したkey値とその値で構成されたObjectを返す。
var x = _.pick({age: 20, sex: "male", country: "JP", name: "HOGA"}, 'age', 'country'); console.log(x); // {age: 20, country: "JP"} var y = _.pick(list, function(val, key, obj){ return _.isNumber(val); }); console.log(y); // {age: 20}
ソースコード
_.pick = function(object, oiteratee, context) { var result = {}, obj = object, iteratee, keys; if (obj == null) return result; if (_.isFunction(oiteratee)) { keys = _.allKeys(obj); iteratee = optimizeCb(oiteratee, context); } else { keys = flatten(arguments, false, false, 1); iteratee = function(value, key, obj) { return key in obj; }; obj = Object(obj); } for (var i = 0, length = keys.length; i < length; i++) { var key = keys[i]; var value = obj[key]; if (iteratee(value, key, obj)) result[key] = value; } return result; };
第二引数が関数の場合、各プロパティに対して渡した関数実行される。 関数でない場合は、指定したkeyのプロパティを第一引数のobjectから取得している。
参考
AtomでXcodeのようにcmd-shift-jで、現在開いているファイルをTree View上で見つける
Atom -> 個人設定 -> Keybindings -> “your keycap file” で下記を追記すればOK。
# 現在開いているファイルをTreeViewで指定する '.platform-darwin': 'cmd-shift-j': 'tree-view:reveal-active-file'
【Underscore.js】_.extendと_.extendOwnを読んだ
jashkenas/underscoreの_.extendと_.extendOwnを読んだ。
概要
_.extend(destination, *sources) _.extendOwn(destination, *sources)
- extend: sourcesに含まれている全てのプロパティ(プロトタイプを含む。)をdestinationにコピーしたものを返す
- extendOwn: sourcesに含まれている全てのプロパティ(プロトタイプは除く)をdestinationにコピーしたものを返す
var Hoge = function(){}; Hoge.prototype.own = false; var a = _.extend({}, {own: true}, new Hoge()); console.log(a); // {own: false} var b = _.extendOwn({}, {own: true}, new Hoge()); console.log(b); // {own: true}
ソースコード
_.extend = createAssigner(_.allKeys); _.extendOwn = _.assign = createAssigner(_.keys); var createAssigner = function(keysFunc, undefinedOnly) { return function(obj) { var length = arguments.length; if (length < 2 || obj == null) return obj; for (var index = 1; index < length; index++) { var source = arguments[index], keys = keysFunc(source), l = keys.length; for (var i = 0; i < l; i++) { var key = keys[i]; if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; } } return obj; }; };
.allKeysでは、自身のプロトタイプのプロパティのkeyまで取得でき、.keysでは自身が持っているプロパティのkeyのみを取得できる。
参考
【Underscore.js】_.mapObjectを読んだ
jashkenas/underscoreの_.mapObjectを読んだ。
概要
_.mapObject(object, iteratee, [context])
objectの各値に第2引数で指定した関数を適用した第1引数を返す。.mapは値の配列を返すが、.mapObjectはオブジェクトを返す。
_.mapObject({age: 20, score: 50}, function(val, key){ return val + 5; }); // {age: 25, score: 55} _.map({age: 20, score: 50}, function(val, key){ return val + 5; }); // [25, 55]
ソースコード
_.mapObject = function(obj, iteratee, context) { iteratee = cb(iteratee, context); var keys = _.keys(obj), length = keys.length, results = {}, currentKey; for (var index = 0; index < length; index++) { currentKey = keys[index]; results[currentKey] = iteratee(obj[currentKey], currentKey, obj); } return results; };
_.mapとは違い、返す値をpushしていくresutlsがオブジェクトになっており、そのkeyには元のオブジェクトのkeyを指定している。
参考
【Underscore.js】_.throttleを読んだ
jashkenas/underscoreの_.throttleを読んだ。
概要
_.throttle(function, wait, [options])
functionを一度目は即時実行して、二回目以降はwaitミリ秒待ってから実行する関数を返す。waitミリ秒までに複数回関数を実行しようとしても、最後に受け付けた関数のみが実行される。
function printCurrTime(num) { console.log(`now: ${_.now()} num: ${num}`); } var printTime = _.throttle(printCurrTime, 5000); printTime(0); printTime(1); // 実行されない printTime(2); // 実行されない printTime(3); // 実行されない printTime(4); // 実行されない printTime(5); // now: 1445396803605 num: 0 // now: 1445396808607 num: 5
ソースコード
_.throttle = function(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; if (!options) options = {}; var later = function() { previous = options.leading === false ? 0 : _.now(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; }; return function() { var now = _.now(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; };
一度目の関数が実行された時刻をpreviousに代入し、クロージャーに渡している。 二回目以降、関数が呼ばれるたびに、残りの時間を設定したsetTimeoutを発行する。