JavaScriptのショートコーディング

プログラムを短くするための覚え書き。

  • 文字列を数値にする
var str = "123";

var num = parseInt( str, 10 ); //10は、10進数にするため
var num = Number( str );
var num = str - 0;
var num = +str;
  • 整数にする
var num = 123.456789;
num = Math.floor( num );
num = num | 0;
num = ~~num;
  • 少数部分を取り出す
num = num % 1;
// %演算子は、余りを求めるが、整数を返すとは限らない
var a = 0;
var b = 0;
var c = 0;

//カンマ演算子を使うと
var a = 0, b = 0, c = 0;

//ただし、下の例はダメ!bとcがグローバル変数扱いになる
var a = b = c = 0;

//やるなら
var a, b, c = a = b = 0;

a = 1; b = 2; c = 3;

c = ( a = 1, b = 2, 3 );
//短くなるわけではないけど
//3個の代入文を1行で行える。if文と組み合わせたり
//()のなかを、カンマで区切ると、最後の値が利用される
  • if文の{ }は、省く
if( a == 6 ) {
  b = c;
}
if(a==6)b=c;//ただし、1命令だけ。

if( a != 6 ) {
  b = c;
  d = e;
}
if(a-6)b=c,d=e;2つ以上ならカンマ
  • if文は式に
if( a != 0 ) { alert( "OK!" ); }
a && alert("OK!"); // 代入式なら()でくくる。

if( a == 0 ) { alert( "OK!" ); }
!a && alert("OK!");
a || alert("OK!");

if( flag ) {
  err = 'out!';
  alert('Error');
}
flag && (err=(alert('Error'),'out!'));
flag && (err='out!')&&alert('Error');
if( x == 0 ) { alert( "OK!" ); } else { alert( "NO." ); }
if(! x ) alert( "OK!" ); else alert( "NO." );
if( x ) alert( "NO." ); else alert( "OK!" );
//3項演算子を使うと
alert(x?"NO.":"OK!");
  • !!を二回連続で使う意味
var f = 1;
if( f ) alert("実行される");
if( !!f ) alert("これも実行される");
alert( !!f) //これは trurを返す
//上は一見無駄な用だけど、ある関数がtrueもしくはfalseしか受け付けない場合に有効

(function( f ) { f === true && alert( "true" ); })(!!1);

//つまり、falseを設定したいとき(0ではない)
f = !1;
//trueを設定したいとき
f = !0;
  • 配列に値を代入する
var ary = new Array();
ary[0] = 0;
ary[1] = 1;
ary[2] = 2;
ary[3] = 3;
ary[4] = 4;

var ary = new Array( 0,1,2,3,4 );
var ary = [0,1,2,3,4];

//これをaからzまでなら
var ary = 'a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z'.split(',');
var ary = 'abcdefghijklmnopqrstuvwxyz'.split('');

//一度きりなら配列にしなくても
alert('abcdefghijklmnopqrstuvwxyz'.split('')[25]);
var str = "abcdefghijklmnopqrstuvwxyz";
var buf = str.match( /(.{3})/g ); //三文字ずつ区切る
var rst;
if( buf ) rst = buf[4];
//もし仮にマッチしなければ、配列にならないので.match()[4]のようにできない

rst = (str.match( /(.{3})/g )||[])[4];
  • for文を変形する
var ary = [1,2,3,4,5,6,7,8,9,10];
var cnt;
var total = 0;

for( cnt = 0; cnt < ary.length; cnt++ ) {
  total = total + ary[ cnt ];
}
alert( total );

//ループでまわして合計を求める
for( var ary=[1,2,3,4,5,6,7,8,9,10], total = 0, cnt = 0; cnt < ary.length; cnt++ ) total += ary[ cnt ];

for( var ary=[1,2,3,4,5,6,7,8,9,10], total, cnt = total = 0, n; n = ary[ cnt++ ]; ) total += n;
//lengthを使わない。ただし配列の中に0やnullや''があるとダメ。

for(var a=[1,2,3,4,5,6,7,8,9,10],t,c=t=0,n;n=a[c++];)t+=n;
//変数名は、やっぱり短く

var a=[1,2,3,4,5,6,7,8,9,10],t,c=t=0,n;while(n=a[c++])t=+n;
//forをwhileに変形。

var t=0,c=10;while(c)t+=c--;
  • 配列をランダムに並び替える
alert([1,2,3,4,5,6,7,8,9].sort( function () { return Math.rand()<.5; } ) );
//ただし、均等にバラけるわけではない。とくに後半は偏る

var ary = [1,2,3,4,5,6,7,8,9];
var func = function () { return Math.rand()<.5; };
alert( ary.sort( func ).sort( func ) );
//二回くらい混ぜたらいけるかもしれない?
  • 文字列の中に、指定した文字が含まれているかの判断
var str ="abcdefghijklmnopqrstuvwxyz";
if( -1 < str.indexOf( "xy" ) ) alert( "含まれています" );
if( /xy/.test( str ) ) alert( "含まれています" );

//もし検索する文字列が、複数ある場合は、正規表現を利用
if( /xy|mn|ab/.test( str ) ) alert( "含まれています" );
//
  • 数値によって文字列を返す。またはその逆。
var x = 0, txt;
if( 0 == x ) txt = "abc";
if( 1 == x ) txt = "aiueo";
if( 2 == x ) txt = "123";
if( 2 == x ) txt = "一二三";

txt = [ 'abc', 'aiueo', '123', '一二三' ][x]; //一行で書ける

//もしくは
'abc aiueo 123 一二三'.split(' ')[x];

//もしこれが逆の場合。(文字列から数値を返す)
var x;
if( "abc"   == txt ) x = 0;
if( "aiueo" == txt ) x = 1;
if( "123"   == txt ) x = 2;
if( "一二三"== txt ) x = 3;

var x = { 'abc':0, 'aiueo':1, '123':2, '一二三':3 }[ txt ]; //一行で書ける


応用編(ってこれが?!)

  • 月末の末日を返す関数
//最初はこんなのだったんだけど、t_netbug様 の参戦で、どんどん短くなっていきました。
function getMatubi(y, m) {
  m--; return (m^m<7|30)-(m==1)*(1+(y%4>0^y%100>0^y%400>0));
}

return (--m^m<7|30)-(m==1)*(1+(y%4>0^y%100>0^y%400>0));
return (m^m>7|30)-(m==2)*(2-(y%(y%100>0?4:400)==0));
return (m^m>7|30)+(m==2)*~(y%(y%100>0?4:400)>0);
//もう正直なところついていけません!凄すぎっ〜!
  • ある範囲を繰り返す(例:角度361度を1度にする)
function kakudo( n ) {
  return n % 360;
}
//マイナスにも対応
  return (n + 360) % 360;
  • 押されたキーにより、X座標を変える
function move( evt ) {
  var kc = evt.keyCode; //[←]なら37、[→]なら39が代入される
  if( 37 == kc ) {
    x = x -2;
    if( x < 0 ) x = 0;
  }
  if( 39 == kc ) {
    x = x + 2;
    if( x > 511 ) x = 511;
  }

  //これは、以下のようにも書ける
  var t = x;
  t = x + ((37 == kc) - (39 == kc )) * 2;
  x = (t < 0) || (511 < t) ? x: t;

  //これは、以下のようにも書ける(試してないけど)
  x+=((1<x&&37==kc)-(x<510&&39==kc))*2;
  
}