[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
JavaScript を書いていると (少なくとも私は) Global 変数が多くなりがちである。これを減らすための書き方。
var hiyoko = {}; // 残念ながらグローバル変数になる (function(){ // この function 内でスコープが切られる var object = hiyoko; // グローバル変数の名前が長い場合はこういうやり方が有効 hiyoko.prototype.hiyokoFunction = function() { callFromHiyokoFunction() }; // callFromHiyokoFunction はスコープ外からは呼べない function callFromHiyokoFunction() { // なんらかの関数を記述 } var myHiyoko = new object(); //これもスコープ外からは参照できない myHiyoko.hiyokoFunction(); })() var myHiyoko = new hiyoko(); myHiyoko.hiyokoFunction(); // 区切った中で宣言されたものも呼べる callFromHiyokoFunction(); // こっちはエラーになる
なお、 Google Closure Lib. を使っているなら goog.scope を使うとよいが、それについてはまた別の時に書く。
小説を読もう!(小説家になろうグループ) 内の検索結果を自分のウェブページに挿入するためのライブラリを書いた。
使うには jQuery が必要 (jQuery のプラグインとして作ってもよかったかもしれない)。
手順としては以下の通り。
var requestBuilder = new com.hiyoko.NarouAPI.NovelAPI.getRequestBuilder();
HTML に次のように記述する。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="http://shunshun94.web.fc2.com/lib/narouNovelAPI.js"></script>
次のようにすると結果を簡単に参照できる。コンソールを使うことですぐに結果を確認できる。
var requestBuilder = com.hiyoko.NarouAPI.NovelAPI.getRequestBuilder(); requestBuilder.limit(112).orderToReviewer.request(function(list, count){console.log(list);});
このライブラリは以下の2つのクラスからなります。
なろう小説APIに送るリクエストを作成・送信するためのクラスです。
リクエストを組み立てるための関数と、リクエストを送るための関数があります。
リクエストして得られる小説の件数の最大値を指定します。最大値は500です (なろう API の仕様による)
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
リクエストして得られる小説の表示開始位置を指定します。たとえば全部で10作品あるとして、3作品目以降の小説情報を取得したい場合は3と指定します。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
閲覧者が多い順に並べます。2016年2月現在、小説家になろうに実装されてない機能であるため無効です。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
ブックマーク数が多い順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
レビュー数が多い順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
総合評価の高い順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
総合評価の低い順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
感想の多い順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
評価した人が多い順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
評価した人が少ない順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
週間の閲覧者数が多い順に並べます。この値は毎週火曜日にリセットされます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
小説本文の文字数が多い順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
小説本文の文字数が少ない順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
N コードが新しい順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
古い順に並べます。
com.hiyoko.NarouAPI.NovelAPI.RequestBuilder:この関数による設定を反映済みの RequestBuilder が返ります
リクエストを小説家になろうのサイトに送信し、コールバック関数で結果を受け取ります。
なし
なろう小説 API の結果を扱う JavaScript オブジェクトです。関数は持たず、プロパティのみ持ちます。
小説のタイトルです。
小説の著者です。
小説のあらすじです。
小説が完結済みか否かを表します。完結済みならば true が返ります。
小説が更新を長期停止しているか否かを表します。停止しているならば true が返ります。
小説に登録された keyword です。
初回掲載日です。YYYY-MM-DD HH:MM:SSの形式で格納されています。
最終掲載日です。YYYY-MM-DD HH:MM:SSの形式で格納されています。
更新日時ですです。YYYY-MM-DD HH:MM:SSの形式で格納されています。
小説の評価点です。
小説のブックマーク数です。
小説の URL です。
小説の著者の URL です。
ユーザにあまり情報を入れさせることなく、ユーザ毎に見えるページを分けたい、ということがある。この場合の選択肢として URI の Query を利用する、という手が考えられる。 (使える場面は限定されるし、本来はログインさせてユーザページとして見せるべきなのかもしれないが)
URL は次のような構造になっている (http://tools.ietf.org/html/rfc3986 から引用)。
foo://example.com:8042/over/there?name=ferret#nose \_/ \______________/\_________/ \_________/ \__/ | | | | | scheme authority path query fragment | _____________________|__ / \ / \ urn:example:animal:ferret:nose
この Query 部分にページに与える引数を与え、ページを開いた際に利用する、という使われ方がされる。例えば https://www.google.co.jp/search?q=ひよことすれば ひよこ で検索することができる。
今回はこの Query パートを JavaScript で取得することを考える。
Query は一般に key と value を = でペアにしたものを & でつないだものである。例えば次のようになる。
?age=22&sex=m&name=koneko
この場合、次のような連想配列のように考えることができる。
{ age: '22', sex: 'm', name:'koneko' }
このような結果を得られるものを目指す。
var com = com || {}; com.hiyoko = com.hiyoko || {}; /** * URL の Query 部分を取得する関数 * @param {Object.<string, string>} Query の連想配列 */ com.hiyoko.getQueries = function() { var params = ((location.search).slice(1)).split('&'); var paramLength = params.length; var result = {}; for(var i = 0; i < paramLength; i++){ var pair = params[i].split('='); result[pair[0]] = pair[1]; } return result; }; // Usage var queries = com.hiyoko.getQueries(); // URL が ~?search_words=ひよこ&type=image ならば // ひよこ が console に出力される console.log('Search Word = ' + queries['search_words']);
Query パートは次のようなルールで書かれる。
上ではさも Query は key=value の形式で記述され、複数個使うときは & でつなぐかのように書いたが、実際のところ Query は次のように言われている。as query components are often used to carry identifying information in the form of "key=value" pairs
(RFC 3986 Section 3.4 Query)、日本語にすればしばしば Query は識別するための情報を扱うために key=value の形式をとる
である (原文ではこの後、それを考慮した扱われ方をするとよい、というような話が続く)。しばしば、であり、常に、ではない点には注意しなければならないかもしれない。
どうしようもない。例えば、 ~?b=d&c&e=f
といった場合、判断のしようがない。もしも & を入れたければパーセントエンコーディング (RFC 3986 Section 2.1 Percent-Encoding)してくれることを期待する。
T. Berners-Lee, R. Fielding, and L. Masinter. RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax. http://tools.ietf.org/html/rfc3986, 2005
JavaScript の動作確認をするのに毎回 .html ファイルと .js ファイルを用意するのは面倒である。かといって、 nodejs (パソコンのコンソール上で動作する JavaScript) をインストールするのが難しい環境もあるだろう。家族共用のパソコンとか。
それでも JavaScript をサッと試すのに便利なツールがある。ブラウザ付属の開発者ツールである。今回は以下のブラウザに付属している開発者ツールで JavaScript を試す方法について簡単に説明する。
勘が良い人はこれだけ読んで試せばあとは読まなくてもいいかもしれない。ブラウザ開いて F12 キーを押し、出てきたコンソールに JavaScript のコードを入力。
とりあえず、ブラウザを開いて F12 を押すと次のような画面が出てくる。しかる後に画面下部の<が記されている部分に JavaScript を入力すると、 JavaScript を即座に実行できる。
Google Chrome の場合も F12 を押して、該当箇所にコードを書いて実行できる。
FireFox も同様に F12 を押して、出てきた箇所にコードを書いて実行できる。
each 関数を使った計算の関数や検索の関数で期待した結果が返ってこない時の対処法。
each 関数が呼び出す callback 関数が返す値は、外側のスコープの関数 (その each 関数を呼んでいる関数) の返り値にはならない。そのため、each 関数を使った計算の関数や検索の関数で期待した結果が返ってこない、ということになってしまうことがある。
下記のコードを実行した際、 console には決められた条件の文字列が表示されることが期待される。しかし、実行すると undefined が返る。
// <Sample Code> /** * 文字列の配列を受け取り、最初に見つかった長さが5である要素を返す * @param {Array.<string>} array 検索対象の配列 * @return {string|undefined} 引数の中で最初に見つかった長さ5の要素 見つからなければ undefined */ var getLengthFive = function(array) { array.forEach(function(v, i) { if(v.length === 5) { return v; } }); }; console.log(getLengthFive(["abc","de","abcde","ab"]));
上記間違った例10行目の return はどの関数の return だろうか。
return は forEach の引数となる関数 (下記例では isLengthFive) のものであり、
外側の関数 (getLengthFive) のものではない。
そのため、 getLengthFive は何も返すことなく終了する。
// <Sample Code> /** * 文字列を受け取り、長さが5であれば引数を返す。そうでなければ undefined を返す * @param {string} array 確認対象の文字列 * @return {string|undefined} 引数の中で最初に見つかった長さ5の要素 見つからなければ undefined */ var isLengthFive = function(v, i) { if(v.length === 5) { return v; } } /** * 文字列の配列を受け取り、最初に見つかった長さが5である要素を返す * @param {Array.<string>} array 検索対象の配列 * @return {string|undefined} 引数の中で最初に見つかった長さ5の要素 見つからなければ undefined */ var getLengthFive = function(array) { array.forEach(isLengthFive); };
each 関数の利用をあきらめ、 for 文の内側でチェックを行う方法。この場合、 return は getLengthFive 関数の return として機能する。
そのため、 getLengthFive 関数は条件にマッチした文字列を返すことができる。
// <Sample Code> /** * 文字列の配列を受け取り、最初に見つかった長さが5である要素を返す * @param {Array.<string>} array 検索対象の配列 * @return {string|undefined} 引数の中で最初に見つかった長さ5の要素 見つからなければ undefined */ var getLengthFive = function(array) { for(var i = 0; i < array.length; i++) { if(array[i].length === 5) { return array[i]; } } }; console.log(getLengthFive(["abc","de","abcde","ab"]));
Array の find 関数を使用する方法が好ましい。
しかしながら、find 関数が使えないブラウザも現時点では多い。
そのため代替手段として解決策1を使うのは手段の一つである。
// <Sample Code> /** * 文字列の配列を受け取り、最初に見つかった長さが5である要素を返す * @param {Array.<string>} array 検索対象の配列 * @return {string|undefined} 引数の中で最初に見つかった長さ5の要素 見つからなければ undefined */ var getLengthFive = function(array) { return array.find(function(v, i) { return v.length === 5; }); };
forEach と find についての詳細は以下を参照。