Shopifyのデフォルトテーマ Debut でカートボタンに現在のカート内の商品の合計数を表示する方法


こんにちは。櫻井です。
ネットショップでお買い物するときに、今いくつ商品カートに入れたっけ?ってなるときありませんか?
スーパーとかで買い物するのとは訳が違ってネットではどれくらい買っているのか目で見てわかりにくいところがあります。
あれもこれもとカートに入れていって気付いたらとんでもない量になっていたなんて経験がある人もいるのではないでしょうか?
なので最低限カートボタンの横に今何品カートに入っているかわかるとユーザーにとって親切だと思うんです。
そこで今回はShopifyでカートボタンにカート内の商品の合計数を表示する方法を説明したいと思います。

まずはliquidを構築

まずはベースとなるliquidを構築します。いろいろ調べると{{ cart.item_count }}でカートないの商品の数を取得できることがわかりました。
以下のソースを商品の合計個数を表示したい場所に書き込んでください。


  <div class="l-header_cart_count"><span class="cart-item-count">{{ cart.item_count }}</span></div>

しかしこれだけだとカートに商品を追加した直後や商品を削除したり下手したときにすぐに反映されません。
なので次はtheme.liquidを開き以下のソースを加えてJSを読み込ませます。


  {{ '//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js' | script_tag }}
  {{ 'api.jquery.js' | shopify_asset_url | script_tag }}

ここからはJSを書き加えます。liquidの準備はこれで終わりです。

JSを書き加える

まずはカートに商品を追加したとき、カート内の商品の数量を変えたときのJSです。
theme.jsを開き「_setCartCountBubble: function(quantity)」を検索してください。
2箇所あるので両方に


  $('.cart-item-count').text(quantity);

を追加します。これでカートに商品を追加したときとカート内で数量を変更したときにもカート全体の商品の個数を変更することができます。
続いて「_onRemoveItem: function(evt) 」を検索し、中にあるdone()の中に


  $('.cart-item-count').text(state.item_count);

を追加します。これで商品をカートから削除したときにもカートないの個数を反映することができます。

まとめ

今回はShopifyのデフォルトテーマ Debut でカートボタンに現在のカート内の商品の合計数を表示する方法を説明しました。本当はデフォルトで読み込まれているJSをいじりたくなかったんですが。新たにJSを追加して行おうとするとバッティングしてしまいうまくいかず止むを得ずこういった形になりました。しかし商品がしっかりユーザーのアクションに合わせて更新できるなんてShopifyってすごいですね。

Shopifyのカートにお届け指定日の項目を追加する方法


こんにちは櫻井です。
今日は商品ページで商品一つずつにお届け指定日を選択してもらうのではなく、カートページで全商品をまとめてお届け日を選択してもらう方法を説明したいと思います。

cart-template.liquid

まずはカートページから編集していきましょう。
Sectionsフォルダからcart-template.liquidを開いてください。
お届け日の選択項目を表示させたい箇所に以下のソースを貼ってください。
この段階ではまだカートページにinput枠が出現するだけです。

<div style="width:300px; clear:both;">
   <p>
     <label for="date">お届け日を指定してください。:</label>
     <input id="date" type="text" name="attributes[date]" value="{{ cart.attributes.date }}" placeholder="{{ "now" | date: "%s" | plus: 86400 | date: "%Y/%m/%d" }}"/>
   </p>
</div>

上のソースを少し解説します。
inputのnameに入っているattributes[date]とvalueに入っている{{ cart.attributes.date }}は会計後の注文完了メールに値を表示させるためのものです。placeholderの中の{{ “now” | date: “%s” | plus: 86400 | date: “%Y/%m/%d” }}には明日の年月日が入ります。
より細かく知りたい方はこの辺りを読んでもらえればわかるかと思います。英語なので大変ですが。。
https://shopify.dev/docs/themes/liquid/reference/objects/cart
https://shopify.github.io/liquid/filters/date/

theme.liquid

次に出現したinput枠にカレンダーから日付を選択できる機能をつけていきます。 今回はjQuery UIを使います。
Layoutフォルダからtheme.liquidを開いてください。
まずはCSSをhead内に読み込ませます。
以下のソースを書き加えてください。

{{ '//code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css' | stylesheet_tag }}

次にJSを読み込みます。

<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js" type="text/javascript" defer="defer"></script>
// 日本語に対応しない場合は以下は不要
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1/i18n/jquery.ui.datepicker-ja.min.js" type="text/javascript" defer="defer"></script>

JSを書き込むときは少し注意してほしいのがデフォルトで読み込まレテいるJSの後に書き込むことです。デフォルトで読み込んでいるものの中にjqueryを読み込ませているものがあるようなのでこれより前でJSを読み込ませるとjQuery UIが動かなくなってしまいます。

JS

必要なJSとCSSは読み込ませることができたので次はJSを記述します。
ファイル名はなんでもいいので新たにJSファイルを作成し
以下のソースを記述してください。

function datePicker() {
  $.datepicker.setDefaults( $.datepicker.regional[ "ja" ] );
  // ↑このソースは日本語の対応が必要ない場合は不要です。
  $("#date").datepicker({
    minDate: +1,
    maxDate: +2
  });
}
datePicker()

記述したらshopifyでJSを読み込ませます。
テーマのソースの編集画面を開き、Assetsフォルダから「新しいassetを追加する」をクリックして先ほどのソースを書き加えたJSを追加します。
次に再びtheme.liquidを開きJSが読み込まれている箇所の一番下に以下のソースを追加してください。

<script src="{{ '〇〇.js' | asset_url }}" defer="defer"></script>

これでカートページにカレンダー機能付きのお届け指定日の項目を追加できました。
しかしこれだけだとメールにお届け指定日が記載されません。
なので次はメールと注文管理を編集していきます。

チェックアウト

まずは注文管理からです。設定からチェックアウトをクリックしてください。
下にスクロールしていくと「注文処理」のところに「追加スクリプト」という項目があります。そこに以下のソースを追加してください。

{{ attributes.date }}

これで注文管理に日付が表示されます。次はメールです。

メール

メールは設定から通知をクリックし、注文管理の「注文の確認」をクリックしてください。
お届け日を追加したい場所に以下のソースを加えてください。

{{ attributes.date }}

まとめ

今回はお届け指定日の項目をカートページに追加する方法を説明しました。最後のテスト配信でダミーでいいから日付が入ってくれるといいんですがそこまではわかりませんでしたが。。
基本的にメールなら箇所でも{{ attributes.date }}でお客さんが入力した日付が取れるはずなので他のメールで使いたい方は試してみてください。

jpgやpngより軽いwebPの話し


こんにちは。櫻井です。
今日はjpgやpngよりもずっと軽いwebpについてお話ししようと思います。
まず、webPはGoogleが開発した静止画像フォーマットで、拡張子に.webpとつきます。

webPのいいところ

webPはとにかく軽いんです。ものによってはpngをwebpに変えただけで4分の1くらい軽くなるものもあります。正直いいところっていうとこのくらいなんですが、この軽くなり方がすごいんです。
1.2mbのものが400kbくらいに落ちると思うとすごいと思いませんか?
元々webサイトの読み込みが遅くなる理由に画像の読み込み速度はかなり大きい部分をしめていると思います。
だって全体の読み込ませているファイル量の割合でみると大半が画像なんだもん。。
例えば、KNAPのホームページだとページ下まで全て読み込ませるとトータル5.7mbファイルを読み込んでいます。そのうち画像は1.8mbです。動画が一番大きくて2.5mb。合わせたら4.3mbです。KNAPのホームページはwebpを読み込ませているのでjpgかpngで書き出していたらおそらく画像は3.6mb~7.2mbくらいになると思います。
こうして考えるとかなり読み込む量を減らせているのがわかっていただけると思います。
webPは軽いくらいしか利点が思い浮かびませんが画質もほとんど落とさずにものすごく軽くできるすごい子なんです。

webPのダメなところ

webPは軽いのはいいんですが、ダメなところもあります。webPが悪いというより主にブラウザが悪いんですが。
まずは対応していないブラウザがある点です。ie11とsafariが対応してません。safariは近々対応するみたい?してる?みたいですが。このせいで対応していないブラウザのために面倒な書き方をしなければいけません。これが二つ目です。
webPを使うときは対応してないブラウザのことも考えて以下のような書き方をします。

 
<picture>
  <source srcset="/img/example.webp" type="image/webp">
  <img src="/img/example.png" alt="example">
</picture>

webPを使うためだけにこんな書き足さないといけないのはちょっと億劫ですよね。ただ軽くなる量を考えたらこのぐらい大したことはないんですが。
webPのダメなところは次が最後ですが最後が一番問題でwebPの生成が面倒な点です。
jpgやpngのようにPhotoshopでそのまま書き出せればそれが一番いいんですが、Photoshopでは書き出せません。なので一度jpgやpngで書き出してからSquooshなどのwebPを生成できるツールを使って書き出す必要があります。全部の画像がまとめてできればそれが一番ですがそうもいきません。Gulpを使えばまとめてできますが、みんながみんなGulpを扱える訳でもありません。webPを使って更新や差し替えになると新たにwebPを作る必要がでます。製作者と同じ人が作業するならいいですが別の人がやるとなるとwebPの作り方をわかっている人じゃないとできなくなります。大変です。
ブラウザが対応してないせいで面倒な書き方をしないといけないことと、生成が面倒なところがwebPの欠点です。

まとめ

今回はwebPについてお話ししました。画像にwebPを使うかどうかのポイントは更新の頻度といかにサイトの重さが気になるかだと思います。これはお客さん次第ですね。後は公開まであまり時間がない時も僕はwebPを使うのは避けてます。管理と記述が大変なので。ただやはり画像の重さがあれだけ軽くなるのを知ってしまうと極力使いたくなります。早くsafariがちゃんと対応してie11が消えて無くなってくれればいいんですが。

while文の特徴とfor文との違いを考えてみる


こんにちは。櫻井です。
最近for文について色々記事を書いてますが、wordpress使ってるとfor文よりwhile文をよく見かける気がします。JSだとfor文を多く見かける気がしますがこの違いはなんなのでしょうか?
なのでまずはwhile文について調べていきたいと思います。

while文

while文は

  
    while(条件式) {
      // 処理する内容
    }
  

基本的にこのような感じで書きます。()の中がtrueの間はずっと{}の中の処理をし続けます。
なので処理する内容のところに条件式の値が変わるようなものが必ず必要になります。
ないと永遠にループし続けて大変なことになります。なので例えばこんな感じになります。

  
    var target = document.querySelector('#js-txt');
    var i = 0;
    var dataItem = [{
      "id": 1,
      "name": "りんご"
      }, {
        "id": 2,
        "name": "みかん"
      }, {
        "id": 3,
        "name": "イチゴ"
      }
      ];
    var i = 0;
    while(i < dataItem.length) {
      // 処理する内容
      target.innerText += `${dataItem[i].id}:${dataItem[i].name}\n `;
      i++;
    }
  

この例だとiがdataItemの中の{}の数より小さかったらtargetにテキストを入れ込んでiに1を足してというのを繰り返してます。
なので結果は

  
    1:りんご
    2:みかん
    3:イチゴ
  

こうなります。for文と一緒ですね。

まとめ

正直for文との違いを調べてもあまりほとんど無そうな感じがしています。
色々読んで見ると
何回処理するか決まっているものはfor文、決まっていないものはwhile文っていう感じで書かれているものをいくつか読みましたが何回処理するかなんて変数で決めればfor文でもwhile文でも一緒では?って思ってしまいます。
あえて違いをあげるとしたら条件式のiの値を好きなタイミングで変えられることでしょうか?使い所を聞かれると困ってしまいますが。あとはfor文よりwhile文の方がif文に似ていてとっつきやすそうな感じがします。
ちなみに処理速度だとほとんど変わらないそうですが若干whileの方が早いみたいです。たくさん処理するものはwhileの方がいいのかも知れませんね。

便利そうで使いづらいfor in


こんにちは。櫻井です。
今回は一見するとシンプルで使いやすそうに見えるけど実はちょっと扱いづらいfor in文について説明したいと思います。

for in文

for in文はfor文と同じくループ処理を行うためのもので、以下のような記述の仕方をします。

    
      for(var a in b){
        // なんか処理
      }
    
  

普通にfor文書くよりシンプルになりました。
for文は「iがdataItem.lengthより小さい間は{}の中の処理をして終わったらiに1を足すっていうのを繰り返してね。iがdataItem.lengthと同じかそれ以上になったら終わっていいよ。」って感じのことが書かれてますが、for in文は「bの中の数の文だけ{}の中の処理をしてね」感じのことが書かれてます。aはどこに行った?ってなりますがaには{}のなかの処理がされるごとに異なるものが入ります。
例えば

    
      var target = document.querySelector('#js-txt');
      var dataItem = [{
        "id": 1,
        "name": "りんご"
        }, {
          "id": 2,
          "name": "みかん"
        }, {
          "id": 3,
          "name": "イチゴ"
        }
        ];

      for(var property in dataItem) {
        target.innerText += `${dataItem[property].id}:${dataItem[property].name}\n `
      }
    
  

この場合だと

    
      1:りんご
      2:みかん
      3:イチゴ
    
  

こんな形で表示されます。aはfor文でいう初期化式といつまでループ処理をするかを決める評価式が足されたようなものだと考えるとわかりやすいかも知れません。

for in文の問題点

ここまでの説明だと楽にできていいじゃんって思えますがそうもいかなくて、for in文は処理する順番を元からある配列を上から処理してくれる保証がないみたいなんです。
僕がテストした感じだと一度も順番が狂ったことはなかったのですが絶対ではないとなると順番通りに流し込まなければならないものなどを扱いづらくなります。
なので順番通りにしたいときは結局for文が一番良さそうです。

まとめ

今回は便利だけど使いづらいfor in文について説明しました。
DOMの生成で順番通りにしたいときには使えそうにないですが、純不動でいいものにはすっきりしていていい気がします。
DOMの生成にはfor文を使いますが、wordpressではwhile文を使うケースが多いのでwhileでもできそうですが、どちらの方がいいんでしょうね?今度検証してみます。

GulpのWebページビルドツール


こんにちは。櫻井です。
今回は僕が普段コーディングで使っているWebページビルドツールを紹介したいと思います。GitHubにあげてあるので使ってみてください。
https://github.com/Sakurai-Yuki/myWebPageBuilder

依存環境

node.jsとnpmは必須です。バージョンによっては動かないこともあるので個人的にはnodebrewを使ってnodeのバージョン管理をすることをおすすめします。
僕が普段使っている環境は
・node v8.10.0
・npm v6.13.6
この環境なら動くと思います。

インストール

プロジェクトごとにコーディングファイルの管理場所は違うと思いますのでそのプロジェクトの位置にmyWebPageBuilderを丸ごと移動させてターミナルでその位置まで移動してください。その後以下を入力してEnterを押せば必要なファイルがインストールされます。

  
    npm install
  

設定ファイル

インストールが終わればそのままでも使えますが、プロジェクトによってcssファイルを置く位置やjsファイルを置く位置が変わると思います。
細かい設定は全て
/gulp/config.js
で行います。

使い方

開発ファイルはsrcディレクトリ内に入れてください。まずは設定の仕方から説明していきます。

設定の仕方

ejsを使う場合は ejsFlag を true にしてください(デフォルトは true )。
sassを使う場合は sassFlag を true にしてください(デフォルトは true )。
sassを使う場合でsourcemapを使う場合は ‘sourcemapFlag’ を true にしてください(デフォルトは true )。
画像を圧縮する場合は imgMinFlag を true にしてください(デフォルトは true )。
画像を圧縮する場合でwebpを使う場合は imgWebPFlag を true にしてください(デフォルトは true )。
JSの圧縮を行いたい場合は jsMinFlag をtrue にしてください(デフォルトは false )。
ローカルサーバーを使用する場合は localServerFlag を true にしてください(デフォルトは true )。
ローカルサーバーを使用する場合を使用する場合でSSIを使用する場合は serverMode を SSI にしてください(デフォルトは normal )。
ローカルサーバーを使用する場合を使用する場合でPHPを使用する場合は serverMode を PHP にしてください(デフォルトは normal )。

ejsの使い方

htmlの吐き出し元となる、ejsファイルをhtmlフォルダの中にいれて開発してください。監視中、ejsフォルダのファイルが更新されると、distフォルダに吐出されます。
共通テンプレートは _include に入れてください。_ から始まるejsファイルはhtmlに書き出されません。
各ページのパス情報やmeta情報は _json フォルダ内の meta.json に記載してください。
ejsのみを書き出したい時はターミナルでgulp ejsと打ち込みEnterを押すと書き出されます。
ejsを使わずにhtmlで開発する場合はdist内に直接htmlファイルをおいてください。

scssの使い方

cssの吐き出し元となる、scssファイルを_scssフォルダの中にいれて開発してください。監視中、scssフォルダのファイルが更新されると、distフォルダに吐出されます。
scssのみを書き出したい時はターミナルでgulp sassと打ち込みEnterを押すと書き出されます。
scssを使わずにcssで開発する場合はdist内にcssファイルをおいてください。

jsの使い方

jsファイルを_jsフォルダの中にいれて開発してください。監視中、jsフォルダのファイルが更新されると、distフォルダに吐出されます。
jsのみを書き出したい時はターミナルでgulp jsと打ち込みEnterを押すと書き出されます。
jsの圧縮する処理が不要の場合はdist内にjsファイルをおいてください。

imgの使い方

imgファイルを_imgフォルダの中にいれて開発してください。監視中、imgフォルダのファイルが更新されると、distフォルダに吐出されます。
webpを生成したい場合も同様に_imgフォルダにimgファイルを入れてください。imgの圧縮やwebpを使用しない場合は、dist内にimgファイルをおいてください。

まとめ

今回は僕が普段使いしているWebページビルドツールをご紹介しました。
自作なのでまだまだ不完全なところがあり、まだ使い勝手に改善の余地はありますが、現状でも充分使えるツールになっていると思っているのでよかったら使ってみてください。

Liquidって何?


こんにちは。櫻井です。
Shopifyの環境構築の仕方について調べれば調べるほどShopifyのテーマに使われているLiquidという言語について理解しないと話にならなのがわかってきました。でも、日本語のドキュメントがまじで全然ないんです。しょうがないので自力でGoogle先生とか周りの人に意味を聞きながらどうにか訳しながらある程度理解できたので今日はLiquidって何?ってところから説明していこうと思います。

Shopifyで使われているLiquidって何?

LiquidはShopifyがRUbyで作成したテンプレート言語でGitHubのオープンソースプロジェクトとして公開されています。shopifyテーマの根幹となっていて動的コンテンツの読み込みに使われます。

Liquidって何ができるの?

Liquidはshopifyストアに入力されたデータを入手してWebページに使用することができます。つまりCMSみたいなことができるってことです。(多分。。)

Liquidの構文

LiquidにはPHPなど、他のプログラミング言語と同様に変数のやり取りやif文のようなロジックや制御、データの出力などができる仕組みがあります。Liquidの構文はHTMLとの区別がつきやすいように区切り文字に囲われています。
{{ }}が変数などのデータの出力を表し、{% %}がif文のようなロジックや制御の流れを表します。
Liquidのコードには主に三つの機能があります。
・Objects
・Tags
・Filters
です。順に説明していきます。

Objects

ObjectsはShopify admminからのデータを出力します。記述の仕方は{{ }}で出力したいデータのオブジェクトを囲む形になります。例えば次のように書きます。

  
    {{ product.title }}
  

この例ではproductというオブジェクトのtitleプロパティを出力します。projectオブジェクトのプロパティについて詳しく知りたい場合はLiquid referenceを読んでみてください。
ちなみに、{{ product.title }}というLiquidオブジェクトはShopifyテーマの商品を登録する箇所の商品のタイトルに当たります。なので、コードがコンパイルされ、商品ページに表示される時、{{ product.title }}には商品のタイトルが入ります。product以外にもLiquidで元から用意されているオブジェクトは他にもありますので詳しく知りたい方は<Liquid objectsのページをみてください。

Tags

Tagsはif文などのロジックやコンテンツの制御をするために使います。Tagsは{% %}で囲って表します。{% %}で囲まれたテキストは{{ }}で囲んだ時のように実際のWebページで表示されるたりはしません。
なので、表品が売り切れていた時と商品がある時で異なる内容を表示させることができます。

  
    {% if product.available %}
    <h2>Price: $99.99</h2>
    {% else %}
    <h2 class="sold-out">Sorry, this product is sold out.</h2>
    {% endif %}
  

この例だと、商品がある場合は「Price: $99.99」が表示され、ない場合は「Sorry, this product is sold out.」が表示されます。
tagsは様々なタイプに分かれているので詳しく知りたい場合はこちらをみてください。
Control flow tags
Iteration tags
Theme tags
Variable tags
Deprecated tags

Filters

filtersはオブジェクトや変数の出力の内容を変更するために使います。filtersはオブジェクトと同じく{{ }}を使いますが、filtersはさらに|を使って表します。例えば次のように表します。

  
    {{ 'hello, world!' | capitalize }}
  

capitalizeは単語の一文字目を大文字に変えてくれるfiltersです。なので出力は「Hello, world!」になります。複数のfiltersを使用することもできます。例えば

  
    {{ 'hello, world!' | capitalize | remove: "world" }}
  

removeは:の後に続く文字列を削除してくれるfiltersです。なので出力は「Hello, !」になります。複数のfiltersを使用する場合は左から右に処理がされて行くので注意してください。
filtersは以下の8つのタイプに分類されます。詳しく知りたい場合はこちらをみてください。
Array filters
Color filters
HTML filters
Math filters
Money filters
String filters
URL filters
Additional filters

まとめ

今回はLiquidって何?っていう根本的なところからお話ししました。どういうものなのか、何ができるものなのかがわかっていただけていたら幸いです。

無料写真素材サイトの紹介


こんにちは。櫻井です。
先日ちょっと無料の素材を探してたんですけど僕が知ってるサイトだとあまりこれといった素材が見当たらなくて困っていた時に他のスタッフに教えてもらった無料素材のサイトが僕の知らないサイトばかりだったので今回は無料写真素材サイトを紹介しようと思います。

O-DAN(オーダン)

https://o-dan.net/ja/
O-DANは複数のサイトから無料写真素材をかき集めてきてくれるサイトです。
ライセンスはそれぞれで違うみたいなのでその都度確認が必要ですが商用利用可の無料写真素材のみにチェックを入れて検索すれば実務で利用できるものも見つけやすそうです。複数のサイトに訪れて探す手間が省けるのがいいですね。

ぱくたそ

https://www.pakutaso.com/
ぱくたそは人物の画像が多めのサイトです。
人が写っている素材が欲しい時にはこちらで探してみるのがいいかも知れません。

Foodiesfeed

https://www.foodiesfeed.com/
食べ物写真しか取り扱っていませんがクオリティの高い画像がたくさんあります。

写真AC

https://www.photo-ac.com/ メールアドレスの登録が必要です。

Unsplash

https://unsplash.com/
海外のものですがfreeみたいです。
海外ってだけで素敵に見える。

カオスになりがちな三項演算子と論理演算子を使って見通しをよくしたい


こんにちは櫻井です。
昔、三項演算子と論理演算子がある程度理解できてこっちの方がすっきりしていいんじゃないか?と思って三項演算子と論理演算子を使ってJSを書いた時があったんですが、数日してそのJSを直す必要が出た時にどこからどこを比較しているのかとかがとにかくわかりづらくてデバックに大苦戦した思い出があります。それ以来、三項演算子と論理演算子を使ってきませんでしたが、使い方さえ誤らなければちゃんと見通しの良いソースができる気がしてきたので振り返りつつ使い所を考えていきたいと思います。

三項演算子

まずは三項演算子について説明していきたいと思います。
カオスの根源みたいなやつです。何度泣かされたことか。
三項演算子はif文の代わりによく使われます。if文を短くしたようなものだと思ってください。
三項演算子の構文は A?B:Cという形で使われます。if文の()の中に当たるのがAで、Aがtrueだった時の処理がB、Aがfalseだった時の処理がCです。まんまif文ですね。
なので例えば

  
    (function () {
      var x = 'hoge';
      if(x == 'hoge') {
        var y = 'fuga';
      } else {
        var y = 'hoge'
      }
    })()
  

こんなif文があったとしたら三項演算子で書くと

  
    (function () {
      var x = 'hoge';
      var y = x == 'hoge' ? 'fuga' : 'hoge';
    })()
  

if文で書いた場合も三項演算子で書いた場合もyの値は同じになります。
このくらいならまだわかりやすいですかね。
次は else if の場合をみていきましょう。

  
    (function () {
      var x = 'fuga';
      if(x == 'hoge') {
        var y = 'fuga';
      } else if (x == 'fuga'){
        var y = 'hoge';
      } else {
        var y = 'piyo'
      }
    })()
  

この場合三項演算子で書くと

  
    (function () {
      var x = 'fuga';
      var y = x == 'hoge' ? 'fuga' : x == 'fuga' ? 'hoge': 'piyo';
    })()
  

だいぶ訳わかんなくなってきました。
三項演算子を使う場合最大でもif elseまでで止めておかないとえらいことになりそうです。
if elseまででも長い処理を三項演算子で書くと見通しが悪くなりそうです。変数の値を他の変数の値次第で変えたい時とかにちょっと使うくらいがちょうどいいかもしれません。

論理演算子

論理演算子はよくif文の()の中に使われている&&や||、!のことです。
&&は論理AND演算子と呼ばれ A && B という形をとります。
if文の中でよく使われるの「AかつBの場合」という風に思いがちですが、実はそうではなくて「Aがtrueの場合はB、Aがfalseの場合はA」という形をとります。
例えば

  
    var x = 'fuga';
    var y = x && 'hoge';
  

この場合はyにhogeが入ります。

  
    var x;
    var y = x && 'hoge';
  

この場合はxは変数名だけ定義されているだけなのでfalseになります。なのでyはundefinedになります。
これを利用してAがtrueだったらBの処理を走らせるってことをするとカオスなことになっていきます。

  
    (function () {
      var target = document.querySelector('#js-txt');
      var x = 'fuga';
      var y = x && (target.innerText += x) && 'hoge';
    })()
  

この場合、#js-txtにfugaを書き込んだ後、yにhogeを入れています。JSの処理の流れをコントロールできるのはいいんですが別にこんな書き方する必要がないしより複雑になってくると一度エラーが出ると何が原因でエラーになったのか無駄にわかりづらくなります。

||は論理OR演算子と呼ばれA||Bという形をとります。
こちらは「AまたはB」と思いがちですが「Aがtrueの場合はA、Aがfalseの場合はB」という形をとります。&&の時とは逆ですね。
こちらはよくみるものだと以下のようなものがあります。

  
    (function () {
      var SCROLL_TOP = window.scrollY || window.pageYOffset;
    })()
  

スクロール量を計測するものですがwindow.scrollYが古いブラウザだとで対応していないので古いブラウザの場合はwindow.pageYOffsetでスクロール量を取得するというものです。

!は論理 NOT演算子と呼ばれ!Aという形で使われます。
これはif文で使うのと変わらず「Aでない場合」という形をとります。

カオスなJSを作らないために

これらを組合せえればif文を使わなくてもJSは書けます。書けはしますがとてつもなく見通しが悪くなります。後になって見直しした時の苦労を考えると三項演算子も論理演算子も使わないに方がいい気もします。
ですが論理OR演算子の例で上げたものはわざわざif文を使って書くよりわかりやすいしシンプルに思えます。
三項演算子と論理演算子の使い所は変数に値を入れ込む時に限り、if文で言うelse ifは使わないようにすればカオスにはならず見通しもよくなるような気がします。

letとconstについて


こんにちは。櫻井です。
変数の定義に今まではvarのみを使っていたのですが。スコープについて調べていく過程でie11でも使えることがわかったのでこれを気に積極的に使っていこうと思い、今回はletとconstについて詳しく調べていこうと思います。

let

letは宣言されたスコープに限定した変数を宣言できます。
この辺りはvarと似たような感じです。
宣言したスコープの中に別のスコープがありその中でまた同じ宣言をした場合です。
varの場合は

  
    (function () {
      var x = 1;
      {
        var x = 2;
        console.log('x1:' + x);
        // x1:2 が出力される
      }
      console.log('x2:' + x);
      // x2:2 が出力される
    })()
  

letの場合は

  
    (function () {
      let x = 1;
      {
        let x = 2;
        console.log('x1:' + x);
        // x1:2 が出力される
      }
      console.log('x2:' + x);
      // x2:1 が出力される
    })()
  

値の出力のされ方が少し異なりますよね。varの場合は宣言されたスコープの中の別のスコープで再度宣言された場合は元から宣言されていたものが上書きされますが、letの場合は宣言されたスコープの中の別のスコープで再度宣言された場合は同じ変数名でも別の変数として扱われるみたいです。
ということはfor文の中にfor文を入れた場合にiをどちらでも定義できそうです。
ちょっとやってみましょう。

  
    (function () {
      var target = document.getElementById('js-txt');
      for(let i = 0; i < 3;  i++) {
        target.innerText += `x1:${i}\n`;
        for(let i = 0; i < 3;  i++) {
          target.innerText += `x2:${i}\n`;
        }
      }
    })()
  

実行すると

  
    x1:0
    x2:0
    x2:1
    x2:2
    x1:1
    x2:0
    x2:1
    x2:2
    x1:2
    x2:0
    x2:1
    x2:2
  

両方iでもちゃんと動きました。これなら、初期化式の変数名で悩むこともなくなりそうです。

const

constは一度定義すると値を変更することができず、再定義することもできません。
なので

  
    (function () {
      const x = 1;
      const x = 2; // エラーになる
      var x = 4; // エラーになる
      let x = 5; // エラーになる
      x = 3; // エラーになる
    })()
  

こんな感じでエラーになります。
なんだか使いずらそうに思うかもしれませんが、値が変わると困るものとかを入れておけば勝手に変わる心配はないし良さそうです。

IE11問題

ie11でも使えるということでletとconstについて調べたんですが困ったことにどうもie11だとletの値の取り扱いが違うみたいです。
Can I use で調べてみたところ
let variables are not bound separately to each iteration of for loops
と書かれています。
要するにループ処理を行うと他のブラウザとは違う処理するよってことみたいです。
ループ処理っていうのはfor文とかwhile文とかですね。
一番使いたいところで使えない。。

まとめ

今回はletとconstについて調べていきました。ie11で使えルトは思っていなかったので驚きです。取り扱いが微妙に異なるのが気になるところですが、これを気に少しずつ使い所を増やして行けたらと思います。

Scroll to top