| 開発者 | ジェレミー・アシュケナス、ジュリアン・ゴングリプ |
|---|---|
| 初回リリース | 2009年10月28日[1] |
| 安定版リリース | 1.13.6 / 2022年9月24日 |
| リポジトリ |
|
| 書かれた | JavaScript |
| サイズ | 7.5 KB 制作 68 KB 開発 |
| タイプ | JavaScript ライブラリ |
| ライセンス | マサチューセッツ工科大学 |
| Webサイト | アンダースコア |
Underscore.jsは、一般的なプログラミングタスクに便利な機能を提供するJavaScriptライブラリです。[2] Prototype.jsやRuby言語が提供する機能に匹敵しますが、オブジェクトプロトタイプを拡張するのではなく、関数型プログラミング設計を採用しています。ドキュメントでは、Underscore.js を「 jQueryの tux やBackbone.jsの suspendersに合うネクタイ」と呼んでいます。Underscore.js は、 Backbone.jsやCoffeeScriptで知られるJeremy Ashkenasによって作成されました。[3]
歴史
ジェレミー・アシュケナスは、 2009年末にBackbone.jsと共同でDocumentCloudプロジェクトのスピンオフとしてUnderscoreを開発しました。これは、 Prototype.js、オリバー・スティールのFunctional JavaScript、ジョン・レジグのMicro-Templatingからインスピレーションを得て、一般的な関数型プログラミングユーティリティを提供するJavaScript用ライブラリの最も初期の1つでした。[4]
2012年、ジョン・デイビッド・ダルトンはアンダースコアのフォークであるLo-Dash(現在のLodash)を作成しました。Lo-Dashは当初、「一貫性、カスタマイズ性、パフォーマンス、その他の機能」を備えたアンダースコアの代替品として宣伝されていました。[5]しかし、Lodashは早い段階で元のアンダースコアのインターフェースから逸脱し[6]、3.0.0リリースでより劇的な変更を開始したため、Lodashユーザーはコードを変更する必要がありました。[7]
2015年5月、ジェレミー・アシュケナスは、ジョン・デイビッド・ダルトンがライブラリを再び統合することについて彼に連絡してきたことを発表しました。コードスタイルとコードサイズに関する懸念にもかかわらず、アシュケナスはLodashの拡張機能の一部をUnderscoreに統合することに反対しませんでした。[8]当時、UnderscoreとLodashに並行して貢献している開発者が数人いました。この貢献者グループは、UnderscoreをLodashに似たものにするために変更を加え始めました。[9]
しかし、この取り組みと並行して、ダルトンはLodashのインターフェースにさらに抜本的な変更を加えた。2015年6月、彼はLodashバージョン4.0.0を発表したが、これはLodashをUnderscoreのインターフェースからさらに遠ざけるものであり、Lodash自体のバージョン3.xシリーズからも大きく逸脱するものであった。[10] [11]これにより、Lodashに依存していたいくつかのプロジェクトは、独自のLodash 3ディストリビューションを作成するようになった。[12]
2016年2月、ダルトンは統合作業が完了したと発表しました。彼は、使用率統計を理由に、ユーザーにアンダースコアからLodashへの切り替えを提案しました。[13]しかし、アンダースコアのメンテナーは、アンダースコアを別のライブラリとして開発することを止めるつもりはないと明言しました。[14]どちらのライブラリも、2016年以降は開発活動が低調な状態になりました。[15] [16]
時間の経過とともに、 ECMAScript標準の新しいバージョンでは、Object.assignやなどの Underscore の機能の一部を再現する組み込み関数が言語に追加されましたArray.prototype.map。ただし、組み込み関数は Underscore の同等の機能よりも強力ではない場合があります。特に、、などの組み込みの配列反復メソッドはmap、プレーンオブジェクトを反復処理できfilterずforEach、反復子の省略形をサポートしていません。[17] [18] [19] [20] [21] [22]
2021年3月現在、UnderscoreはJulian Gonggrijpによって積極的に開発されており、2020年3月から大きな貢献を開始しています。 [15]このライブラリは今でも広く利用されており、毎週数百万回npmからダウンロードされています。 [23]
コンテンツ
本質的に、Underscore は次の 3 つの機能を提供します。
- 日常のアプリケーションで実際に役立つことを目的とした、100 を超える再利用可能な関数のコレクションです。ドキュメントでは、いくつかのカテゴリを区別しています。
find、、/ 、などのコレクション関数は、データのコレクションを処理します。これらの関数はmap、配列のようなシーケンスの要素だけでなく、オブジェクトのプロパティに対しても操作できます。minmaxgroupByshufflefirst/last、flatten、などの配列関数はchunk、zip配列のようなオブジェクトに対してのみ動作します。bind、、などの関数はmemoize、関数partialをdebounce引数として受け取り、変更されたプロパティを持つ新しい関数 (高階関数) を返します。- オブジェクト関数はより基礎的なカテゴリであり、Underscoreの内部でも再利用される多くの関数が含まれています。[24]これは大まかに2つのサブカテゴリに分けられます。
isNumber、isElement、などの型テスト関数isDataView。keys、、extend/ 、などの関数はpick、(プレーンな)オブジェクトをデータとして操作します。omitpairsinvert
- ユーティリティ関数は残りのカテゴリです。特に、これには自明な関数
identityとnoop文字列操作関数escape、unescapeおよびが含まれます。このカテゴリには、ポイント 2 のように特別な機能と見なすことができるtemplate関数とも含まれます。iterateemixin
chainや などの特別な機能はiteratee、ポイント 1 の関数と組み合わせることで、より短く、より簡潔な構文を実現します。_ライブラリの名前の由来となった特別な関数 は、これらの機能の中心です。- 読みやすいように設計された文芸的なソースコード。これにより、ライブラリの実装方法を簡単に把握できます。ドキュメントには、ソースコードのレンダリングされたバージョンが含まれており、コメントは左側、ロジックは右側にあります。コメントはMarkdown を使用してフォーマットされ、ロジックは構文が強調表示されます。バージョン 1.11 以降、Underscore はモジュール化されています。このため、ドキュメントには、各関数が別のページにあり、
import参照がクリック可能なハイパーリンクである注釈付きソースのモジュールバージョンと、すべての関数が依存関係の順序で 1 つのページにある単一の読み取りバージョンの両方が含まれるようになりました。
機能の概要と例
Underscore は関数型スタイルを推進しており、複数の関数を 1 つの式に組み合わせて新しい機能を実現できます。たとえば、次の式では 2 つの Underscore 関数を使用して、単語を最初の文字でグループ化しています。
'underscore'から{ groupBy 、first }をインポートします。
groupBy ([ 'アボカド' , 'アプリコット' , 'チェリー' , 'デーツ' , 'ドリアン' ], first );
// 結果:
// { a: ['アボカド', 'アプリコット'],
// c: ['チェリー'],
// d: ['日付', 'ドリアン']
// }
アンダースコア関数は、ユーザー定義関数とはまったく区別されません。ユーザーが独自のfirst関数を実装した場合でも、上記の式は同様に機能します。
'underscore'から{ groupBy }をインポートします。
const first =配列=>配列[ 0 ];
groupBy ([ 'アボカド' , 'アプリコット' , 'チェリー' , 'デーツ' , 'ドリアン' ], first );
ただし、Underscore が提供する関数セットは、そのような労力を最小限に抑えるように特別に選択されているため、ユーザーは独自の関数を作成するのではなく、既存の関数から機能を構成できます。
配列またはオブジェクトの内容を反復処理する関数は、通常、データを最初のパラメータとして受け取り、反復関数または反復対象を 2 番目のパラメータとして受け取ります。上記の例では、firstは に渡される反復対象ですgroupBy。
イテレータはこれらを使用する必要はありませんが、ほとんどの場合、次の 3 つの引数を受け取ります: (1) コレクション内の現在の位置の値、(2) この値のキーまたはインデックス、(3) コレクション全体。次の例では、pickキーが大文字で始まるオブジェクトのプロパティのみを選択するために、イテレータで 2 番目の引数が使用されています。
'underscore'から{ pick }をインポートします。
定数の詳細= {
公式:「ヴォルフガング・アマデウス・モーツァルト」、
非公式:「ウルフィー」
};
const keyIsUpper = (値,キー) =>キー[ 0 ] ===キー[ 0 ] .toUpperCase ();
pick (詳細、keyIsUpper );
// {公式:「ヴォルフガング・アマデウス・モーツァルト」}
前述の で説明したように、多くの Underscore 関数は反復子として使用できますfirst。それ以外にも、反復子の省略形を使用することで、反復子関数を記述せずに済む一般的なケースがいくつかあります。次の例では、オブジェクトの配列から
'name'すべてのプロパティを抽出するために、文字列が反復子の省略形として使用されています。name
'underscore'から{ map }をインポートします。
定数人= [
{名前: 'リリー' 、年齢: 44 、職業: '司書' },
{名前: 'ハロルド' 、年齢: 10 、職業: '夢想家' },
{名前: 'サーシャ' 、年齢: 68 、職業: 'ライブラリ開発者' }
];
map ( people , 'name' ); // ['リリー', 'ハロルド', 'サーシャ']
groupBy上で示したおよび関数を含む「コレクション」カテゴリのすべての関数はmap、配列のインデックスとオブジェクトのキーの両方を反復処理できます。 これは、次の で示されますreduce。
'underscore'から{ reduce }をインポートします。
定数を追加します。
const sum = numbers => Reduce ( numbers 、add 、0 ) 。
合計( [ 11,12,13 ] ) ; // 36
合計({アリス: 9 ,ボブ: 9 ,クレア: 7 }); // 25
配列やオブジェクトを反復処理する関数以外にも、Underscore はさまざまな再利用可能な関数を提供します。たとえば、throttle関数が評価される頻度を制限します。
'underscore'から{ throttle }をインポートします。
// スクロールイベントは頻繁に発生するため、次の行は
// ブラウザの速度が低下します。
document.body.addEventListener ( ' scroll ' , expensiveUpdateFunction ) ;
// 評価を 100 ミリ秒ごとに 1 回に制限します。
const throttledUpdateFunction = throttle ( expensiveUpdateFunction , 100 );
// ユーザーエクスペリエンスが大幅に向上しました!
document.body.addEventListener ( ' scroll ' , throttledUpdateFunction ) ;
もう 1 つの例は でdefaults、これはまだ設定されていない場合にのみオブジェクトのプロパティを割り当てます。
'underscore'から{ defaults }をインポートします。
constリクエストデータ= {
URL : 'wikipedia.org' 、
メソッド: 'POST' 、
本文: '記事本文'
};
定数デフォルトフィールド= {
メソッド: 'GET' 、
ヘッダー: { 'X-Requested-With' : 'XMLHttpRequest' }
};
デフォルト( requestData 、defaultFields );
// {
// URL: 'wikipedia.org',
// メソッド: 'POST',
// 本文: '記事本文',
// ヘッダー: {'X-Requested-With': 'XMLHttpRequest'}
// }
機能_
アンダースコアは、複数の目的を果たす関数 に由来しています_。
ラッパー関数
関数として、_最初の引数として渡された値のラップされたバージョンを返します。この特別なオブジェクトには、すべての Underscore 関数がメソッドとして含まれているため、「OOP スタイル」と呼ばれる別の表記法が有効になります。
'underscore'から_ 、{ last }をインポートします。
// 「通常」または「機能的」スタイル
最後([ 1 , 2 , 3 ]); // 3
// 「OOP スタイル」
_ ([ 1 , 2 , 3 ]).最後() // 3
この機能は連鎖で使用されます(次のセクション)。 メソッドを使用して値を再度アンラップし.value()、Underscore の外部でさらに処理することができます。場合によっては、値が自動的にアンラップされることもあります。
// 明示的なアンラップ
_ ([ 1 , 2 , 3 ]). value () // [1, 2, 3]
// 数値に強制変換されたときに自動的にアンラップします
1 + _ ( 2 ) // 3
// 文字列に強制変換されたときに自動的にアンラップされます
'abc' + _ ( 'def' ) // 'abcdef'
// JSON としてフォーマットされている場合は自動的にアンラップされます
JSON . stringify ({ a : _ ([ 1 , 2 ]) }) // '{"a":[1,2]}'
部分的なアプリケーションプレースホルダー
_関数のプレースホルダーとしても機能しますpartial。部分的に適用された関数のバージョンpartialを作成し、一部のパラメータを「オープン」のままにして、後で提供できるようにするために使用できます。たとえば、概要の例を次のように拡張して、式を再利用可能な関数に変換できます。
_groupBy
'underscore'から_ 、{ partial 、groupBy 、first }をインポートします。
const groupByFirstChar = partial ( groupBy 、_ 、first );
groupByFirstChar ([ 'アボカド' , 'アプリコット' , 'チェリー' , '日付' , 'ドリアン' ]);
// { a: ['アボカド', 'アプリコット'],
// c: ['チェリー'],
// d: ['日付', 'ドリアン']
// }
groupByFirstChar ([ '栗' , 'ピスターシュ' , 'クルミ' , 'カシュー' ]);
// { c: ['栗', 'カシューナッツ'],
// p: ['ピスタッシュ'],
// w: ['クルミ]
// }
カスタマイズポイント
さらに、 は、ユーザーが Underscore 関数の動作をニーズに合わせて調整できる中心的なカスタマイズ_ポイントとして機能します。具体的には、ユーザーは をオーバーライドして新しい iteratee ショートカットを作成したり、関数をカスタマイズしたりできます。
_.iteratee_.templateSettingstemplate
名前空間ハンドル
より一般的には、すべてのアンダースコア関数は のプロパティとして存在します_。たとえば や_.mapも存在します。これにより、 を名前空間ハンドルとして_.debounce使用できるようになります。ES6でモジュールが導入されたことにより、このような名前空間ハンドルを持つことは厳密には必要ではなくなりましたが、 AMDやCommonJSなどの古いモジュール システムを使用するコードでは、この方法が依然としてよく見られます。
_
var _ = require ( 'アンダースコア' );
_ . groupBy ([ 'アボカド' , 'アプリコット' , 'チェリー' , 'デーツ' , 'ドリアン' ], _ . first );
既存の慣例を考慮すると、別のライブラリの同じ名前の関数ではなく、特に Underscore ライブラリの関数を意味していることを明確にするための便利な表記法になることもあります。たとえば、Underscore と Async はどちらも という名前の関数を提供します。これらを区別するには、それぞれ およびとeach記述します。
_.eachasync.each
連鎖
この関数は、chain_ 関数によって生成されたラッパーの修正バージョンを作成するために使用できます。このような連鎖ラッパーで呼び出されると、各メソッドは新しいラッパーを返すため、ユーザーはアンダースコア関数を使用して中間結果を処理し続けることができます。
'underscore'から{ chain }をインポートします。
定数square = x => x * x ;
定数isOdd = x => x % 2 ;
チェーン([ 1 , 2 , 3 , 4 ]).フィルター( isOdd ).マップ( square ).ラスト()
// 9のラッパーを返す
returnUnderscore で実装された関数が、次のように終わるチェーンを持つステートメントのみで構成されることは珍しくありません.value()。
const add = ( x , y ) => x + y ;
// 数値の配列が与えられた場合、その二乗の合計を返します。
// これらの数値。これは統計ライブラリで使用できます。
関数sumOfSquares (数値) {
戻り値チェーン(数字)
.地図(正方形)
.減らす(追加する)
。価値();
}
チェーンは、Underscore に同梱されている関数に限定されません。ユーザーは、mixin関数に渡すことで、独自の関数のチェーンも有効にできます。
'underscore'から、reduce 、mixin をインポートします。
const sum = numbers => Reduce ( numbers 、add 、0 ) 。
ミックスイン({合計,平方});
チェーン([ 1 , 2 , 3 ]). map ( square ). sum (). value (); // 14
チェーン([ 1 , 2 , 3 ]).合計().平方().値(); // 36
実際、アンダースコア自身の関数でも、まさにこの方法で連鎖が有効になります。アンダースコアのすべての関数は、連鎖のための特別な準備なしに通常のスタンドアロン関数として記述され、その後_関数に「混ぜ込まれます」。[25]
Iteratee の省略形
以前概要で述べたように、配列やオブジェクトを反復処理するほとんどの Underscore 関数は、関数ではなく iteratee という省略表記を受け入れます。ここでそのセクションの例を繰り返します。
'underscore'から{ map }をインポートします。
定数人= [
{名前: 'リリー' 、詳細: {年齢: 44 、職業: '消防士' }}、
{名前: 'ハロルド' 、詳細: {年齢: 10 、職業: '夢想家' }},
{名前: 'Sasha' 、詳細: {年齢: 68 、職業: 'ライブラリ開発者' }}
];
map ( people , 'name' ); // ['リリー', 'ハロルド', 'サーシャ']
内部的には、この表記は、_.iteratee関数を取得するために短縮値を渡すことによって有効になります。_.iterateeデフォルトでは、Underscore に付属する関数に設定されiteratee、値に応じて次のように関数を返します。
パス
値が文字列の場合、iterateeその値を に転送しproperty、文字列をプロパティ キーとして解釈します。引数から指定されたキーを持つプロパティを抽出しようとする関数を返します。次の式はすべて同等です。
'underscore'から{ iteratee 、property }をインポートします。
map (人, '名前' );
map ( people 、iteratee ( 'name' ));
マップ(人、プロパティ( '名前' ));
map ( people 、obj => obj && obj [ 'name' ] )。
// ['リリー'、'ハロルド'、'サーシャ']
配列と数値も に渡されますproperty。配列を使用してネストされたプロパティを取得できます。
map (人, [ '詳細' , '職業' ] );
// ['消防士', '夢想家', 'ライブラリ開発者']
数字は配列や文字列のインデックスとして使用できます。これらすべてを組み合わせると、次の式を使用して、人の職業の 2 番目の文字としてアルファベットの文字が何回出現するかをカウントできます。
'underscore'から{ countBy }をインポートします。
countBy (人, [ '詳細' , '職業' , 1 ]); // {i: 2, r: 1}
属性ハッシュ
値がオブジェクトの場合、iterateeはそれを に転送し、オブジェクトを一致する必要がある属性のセットとして解釈します。 は、引数に同じ属性セットがあるかどうかに応じてまたはmatcherを返す関数を返します。
truefalse
'underscore'から{ find }をインポートします。
find (人、{名前: 'Sasha' } ) ;
// {名前: 'Sasha'、詳細: {年齢: 68、職業: 'ライブラリ開発者'}}
find (人、{ name : 'Walter' });
// 未定義
nullそしてundefined
値がnullまたは の場合undefined、Underscore が としてエクスポートする恒等関数iterateeを返します。これを使用して、コレクションから真の値をフィルタリングできます。
identity
'underscore'から{ filter 、iteratee 、identity }をインポートします。
const example = [ 0 , 1 , '' , 'abc' , true , false , {}];
// 次の式はすべて同等です。
フィルター(例);
フィルター(例、未定義);
filter ( example 、iteratee ( undefined ) ) ;
フィルター(例、ID );
// [1, 'abc', true, {}]
上書き_.iteratee
ユーザーは、カスタムのショートカットを作成するために _.iteratee をオーバーライドできます。次の例は、これを使用して正規表現フィルタリングを実装する方法を示しています。
輸入{
iteratee を元のIterateeとして、
正規表現、
ミックスイン、
フィルター、
} は'アンダースコア'から派生します。
関数iteratee (値、コンテキスト) {
if ( isRegExp (値)) {
文字列=>値を返します。テスト(文字列);
}それ以外{
元のIteratee (値、コンテキスト)を返します。
}
}
ミックスイン({ iteratee });
filter ([ '本当に' , 'すごい' , '素晴らしい' , 'ズボン' ], /ab/ );
// ['本当に', '素晴らしい']
参照
参考文献
- ^ リリース 0.1.0、jashkenas/underscore、GitHub
- ^ "Underscore.js – Fokus を使用したアイン クライネス フレームワーク". entwickler.de (ドイツ語)。 2018 年 6 月 20 日。2020 年7 月 9 日に取得。
- ^ 「JavaScript Meetup City」、Open、ニューヨークタイムズ、2012年4月4日
- ^ Ashkenas, Jeremy. 「Underscore 0.4.0 ソース」. cdn.rawgit.com . 2021年3月1日閲覧。
- ^ “Lo-Dash v2.2.1”. lodash.com . 2013年11月6日時点のオリジナルよりアーカイブ。2021年3月1日閲覧。
{{cite web}}: CS1 メンテナンス: 不適切 URL (リンク) - ^ 「Lodash Changelog - 1.0.0 rc1」. github.com . 2012年12月4日. 2021年3月1日閲覧。
- ^ 「Lodash Changelog - 3.0.0」。github.com。2015年1月26日。 2021年3月1日閲覧。
- ^ Ashkenas, Jeremy (2015年5月21日). 「The Big Kahuna: Underscore + Lodash Merge Thread」. github.com . 2021年3月1日閲覧。
- ^ 「Underscore: 2015 年 5 月 21 日から 2015 年 10 月 1 日までの重大な変更を含むプルリクエストをマージしました」。github.com。2021年3 月 1 日閲覧。
- ^ Dalton, John-David (2015年6月8日). 「'Core API' に関するコメント」. github.com . 2021年3月1日閲覧。
- ^ “Lodash changelog 4.0.0”. github.com . 2016年1月12日. 2021年3月1日閲覧。
- ^ “@sailshq/lodash”. npmjs.com . 2021年3月1日閲覧。
- ^ Dalton, John-David (2016年2月13日). 「Merge update」. github.com . 2021年3月1日閲覧。
- ^ Krebs, Adam (2016年2月17日). 「「マージ更新」へのコメント」. github.com . 2021年3月1日閲覧。
- ^ ab "jashkenas/underscore Insights: Contributors". github.com . 2021年3月1日閲覧。
- ^ 「lodash/lodash Insight: Contributors」. github.com . 2021年3月1日閲覧。
- ^ “Array.prototype.map”. developer.mozilla.org . 2021年3月1日閲覧。
- ^ “Array.prototype.filter”. developer.mozilla.org . 2021年3月1日閲覧。
- ^ “Array.prototype.forEach”. developer.mozilla.org . 2021年3月1日閲覧。
- ^ “_.map”. underscorejs.org . 2021年3月1日閲覧。
- ^ “_.filter”. underscorejs.org . 2021年3月1日閲覧。
- ^ “_.each”. underscorejs.org . 2021年3月1日閲覧。
- ^ “underscore”. npmjs.com . 2021年3月1日閲覧。
- ^ Gonggrijp, Julian. 「modules/index.js」. underscorejs.org . 2021年3月5日閲覧。
- ^ Gonggrijp, Julian. 「modules/index-default.js」. underscorejs.org . 2021年3月4日閲覧。
外部リンク
- 公式サイト
- Oliver Steele による機能的な Javascript (インターネット アーカイブ。osteele.com にはスクリーンショットのみが保存されています)
- John Resig による JavaScript マイクロテンプレート。_.template の元となったものです。
