関数リテラル入れ子案:Animating Symbols|Google Maps JavaScript API|Google Developers
さて基本的なアニメーションシンボルのサンプルソースから、
より見やすくメンテナンスしやすい書き方はないものかと、
無名関数を次は関数リテラルとして記述する例をご紹介します。
個人的にはこの記述で決まりかなと思います。
なお、本投稿は以下からの続きです。
サンプルソースについては以下でご紹介しています。
関数リテラル入れ子案:Animating Symbols
無名関数では読みにくいし、触りにくい。
別定義関数ではデグレードしてします。
無名関数にパラメータで値を渡しつつも、IEで互換性を保つ記述方法が必要です。
そこで以下のような記述に変更します。
これは無名関数をリテラル記述(定数化・変数化)に変更し、変数に格納しています。
1 2 3 4 5 6 7 8 9 10 11 |
function animateCircle(p_line, p_count) { var anonyfunc = function() { p_count = (p_count + 1) % 200; console.log(p_count); var icons = p_line.get('icons'); icons[0].offset = (p_count / 2) + '%'; p_line.set('icons', icons); } window.setInterval(anonyfunc, 20); } |
上記のサンプルは以下で表示しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<script type="text/javascript"> function initMap() { var map = new google.maps.Map(document.getElementById('map3'), { center: {lat: 20.291, lng: 153.027}, zoom: 6, mapTypeId: google.maps.MapTypeId.TERRAIN }); // Define the symbol, using one of the predefined paths ('CIRCLE') // supplied by the Google Maps JavaScript API. var lineSymbol = { path: google.maps.SymbolPath.CIRCLE, scale: 8, strokeColor: '#393' }; // Create the polyline and add the symbol to it via the 'icons' property. line = new google.maps.Polyline({ path: [{lat: 22.291, lng: 153.027}, {lat: 18.291, lng: 153.027}], icons: [{ icon: lineSymbol, offset: '100%' }], map: map }); var count = 0; animateCircle(line, count); //parameter add } function animateCircle(p_line, p_count) { var anonyfunc = function() { p_count = (p_count + 1) % 200; var icons = p_line.get('icons'); icons[0].offset = (p_count / 2) + '%'; p_line.set('icons', icons); } window.setInterval(anonyfunc, 20); } google.maps.event.addDomListener(window,"load",initMap); $('#ver').text(google.maps.version); </script> |
※2017/02/23:訂正ライブラリの読み込み忘れによって地図が表示されていませんでした。
表示されるよう訂正しました。
補足
またこの記述にて、以下のようにパラメータの値を、
そのまま無名関数内部で利用しています。
function animateCircle(p_line, p_count) {
var anonyfunc = function() {
p_count = (p_count + 1) % 200; ...}
これについては、
以下のように入れ子で定義した関数による スコープが内包されることによって実現されています。
多重に入れ子にされた関数
関数は多重に入れ子にすることができます。つまり、関数 (A) が関数 (B) を含み、関数 (B) が関数 (C) を含む事ができます。このとき関数 B と C はともにクロージャを形成するので、B は A にアクセスでき、C は B にアクセスできます。さらに、C が アクセスできる B は A にアクセスできるので、C は A にアクセスすることもできます。このように、クロージャは複数のスコープを持つ事ができます。クロージャはそれを内包する関数のスコープを再帰的に内包しています。これは スコープチェーニング (scope chaining) と呼ばれます。(なぜ「チェーニング」と呼ばれるのかは後で説明します。)
この記述方法は以下サイトを参考に記述をしたものです。
関数リテラルは配列リテラルやオブジェクトリテラルなどと同じように変数に代入することができます。
var func = function(引数1, 引数2, …){実行する処理;};
この場合、配列の場合などと同じく関数リテラルに対する参照が変数に代入されることになります。
また関数リテラルを変数に代入せずに関数リテラルを直接呼び出すこともできます。
(function(引数1, 引数2, …){実行する処理;})(引数1, 引数2, …);具体的には次のように記述します。
var num = (function(x, y){return (x + y)/2;})(10, 8);上記の場合、変数numには(10 + 8)/2の結果である9が代入されることになります。
個人的にはこの記述の方がメンテナンスしやすい
個人的な印象になりますし、好き嫌いはあると思います。
私は、無名関数部分を別で記述し変数に格納しておき、
window.setInterval()で呼び出すこの記述は、
インターバル動作部分の導入が綺麗ですっきりしていると思います。
無名関数を入れ子にする形を取る事で、
window.setInterval()側にパラメータを渡すこともなく、
グローバル変数を利用することもなく、
値の受け渡しができます。
私はこの方法で落ち着こうかなと思っています。
当サイトにお越しいただきありがとうございます。
当サイトは管理人アルゴリズンが個人で作成を行っているものです。
Google Inc.様とは一切関係はありません。
当サイト内のコンテンツの引用・出典の明記なきものは、
すべて管理人アルゴリズンが著作権を保持するオリジナルコンテンツです。
当サイトでご紹介しております写真等がある場合にも著作権の放棄は致しません。
申し訳ございませんが、無断転載、複製をお断りさせて頂いております。
尚、サイト内コンテンツを引用される際にはご連絡は不要です。
ただし、出典元として当サイト(個別URL)へのリンクをお願いいたします。
コンテンツを有益であると感じていただけましたら非常に光栄です。
ありがとうございます。
記事の作成依頼・更新依頼・削除要請などのご意見ご要望は、
まず、Twitter等よりメンションまたは、メッセージでご連絡を頂けますと幸いです。
@algorhythnn|Twitter
algorhythnn|Google+
algorhythnn|Facebook
運営者はSNS等で個人名等の公開は行わないポリシーで運営しております。
直接のご連絡・取材時などには個人名・屋号でご連絡を差し上げる場合もございますが、
個人名・屋号等をインターネット上で公開されることはご遠慮願います。
公開日:
最終更新日:2017/02/23