slowjet

is a part of a carburetor

コールスタックを辿って、関数が呼ばれた元の位置を知る

プロジェクトが長くなってくると、前に書いたはずのコードも忘れがちだよね…
あれ、なんでこれ2回も呼ばれてるの、記憶にないんだけど(いやいや前に書いてる

Chrome なら Error オブジェクトの stack で辿れる

function hoge() {
  var err = new Error();
  err.stack;
}

function fuga() {
  hoge();
}

fuga();

console.trace() が存在するブラウザであればそれでも OK

function hoge() {
  console.trace();
}

...

表示もちょっと違うけど、Chrome はエラーオブジェクトの stack のほうが見やすかった

Resources

BLOB とは何か

a[download] と Blob で任意のファイルを作ってダウンロードさせる
で唐突に出てきた BLOB という物が何かという説明をちょっと。

32KB以上の大きなデータを扱う場合は、
Large Object(LOB) Data Types を利用する。
BLOB はこれのひとつで、Binary Large OBject の略。
Binary とあるように、BLOB は文字列はもちろん、
巨大な画像、音声ファイル、動画ファイルなどを扱うことができる。

Large Object Data Types には他にも

  • CLOB (Character Large OBject)
  • DBCLOB (Double Byte Charater Larget OBject)

などがある。

File API で定義されているのは Blob インターフェースのみ、
つまり File API を通して利用できるのは BLOB だけ。

BLOB 自体は Binary Large OBject の略なので BLOB 表記が正しいが
File API で定義されているのは Blob インターフェースなので Blob と表記している。
ので、表記揺れではありません。

Blob インターフェースを通して BLOB を扱う。

Blob オブジェクトに

var blob = new Blob([blobParts], blobPropertyBag);

// blobParts: ここで指定したデータを元に Blob オブジェクトを作る
// 基本的には DOMString ≒ String(文字列)でOK
// blobPropertyBag: typeのみ、MIME-TYPE を指定する { type: 'text\/plain' }
// デフォルトは UTF-8 でエンコーディングされるが、charset で指定することも可能
// { type: 'text\/plain;charset=UTF-8' }

var data = { a: 1 };
var blob = new Blob([JSON.stringify(data)], { type: 'application\/json' });

// => Blob {type: "text/javascript", size: 7, slice: function}

FileReader で Blob を読み出し

FileReader についてはまた別途書く

var fileReader = new FileReader();
fileReader.addEventListener('load', function() {
  console.log(fileReader.result);
}, false);
fileReader.readAsText(blob);

// => {"a":1}

Resources

Backbone の collection 全てを destroy する

前書いたと思ってたけど書いてなかった。

destroy で DELETE も同時に行う。

collection.each(function(model) {
  model.destroy();
});

これだと、destroy 実行で collection から model が削除されて
length が変わってしまうので、ダメ

_.each(collection.pluck('id'), function(id) {
  collection.get(id).destroy();
});

こうする

a[download] と Blob で任意のファイルを作ってダウンロードさせる

これを JSON ファイルとして保存したい

{ hoge: 1, fuga: 2, piyo: 3 }

インターフェース

<a href="#" class="download disabled">ダウンロード</a>

1. Blob(*) を使ってバイナリデータを作る

var a = document.querySelector('.download');
var obj = { hoge: 1, fuga: 2 , piyo: 3 };
var blob = new Blob(
  [JSON.stringify(obj)],
  { type: 'application\/json' }
);

2. blob を元に URL.createObjectURL で URL を作る

var url = URL.createObjectURL(blob);

3. A要素からダウンロードできるように属性値をセット

a.href = 'data.json';
a.download = url;

a.classList.remove('disabled');

Code

var a = document.querySelector('.download');
var obj = { hoge: 1, fuga: 2 , piyo: 3 };
var blob = new Blob(
  [JSON.stringify(obj)],
  { type: 'application\/json' }
);
var url = URL.createObjectURL(blob);

a.download = 'data.json';
a.href = url;
a.classList.remove('disabled');

Demo

使えるブラウザは Can I use... とか参照してください。
今だと ChromeFirefox だけかな

後でもうちょっと詳しいことも書くか。。 BLOBとは何か

*) Blob

Resources

$.when には Deferred の配列を渡せない

どうも JS Deferred の癖が残っているようでいつもやってる気がする

function hoge() {
  var dfrs = [];
  _.each(arr, function(obj) {
    var $dfr = $.Deferred();
    dfrs.push($dfr);
  
    // 完了したら $dfr.resolve();
  });

  return $.when(dfrs);
}

これだとだめ。最後のところを

return $.when.apply(null, dfrs);

で、引数を配列で渡せるようにする

preventDefault()の位置に悩む

どこに書いても気持ち悪いなんとかしてください
気持ち的にはこれなんだけど

$('a').click(function(e) {
  e.preventDefault();

  var self = this;
  // hogehoge
});

ちきしょう、varを先頭にまとめたいぜ・・・
かといって

$('a').click(function(e) {
  var self = this;
  // hogehoge

  e.preventDefault();
});

気分的には、最初にpreventDefault()って書いておきたい。いやだから→ループ

WebStormでJSHintのglobalsを設定する

もちろんコメントでも指定できるけど

f:id:nori_17:20130302135424p:plain

f:id:nori_17:20130302135436p:plain

Settings>JavaScript>Code Quality Tools>JSHintPredefined でも設定できる。
Librariesに登録してるものはこれで指定してしまってもいいかも。

f:id:nori_17:20130302135444p:plain

ところでWebStorm6からはJSHintの設定UIが大幅に変わって、詳細に指定できるようになる様子。

f:id:nori_17:20130302143942p:plain