【JSONP】『ステートフルJavaScript』を読了した

プログラミング言語とアイデアの実行速度

プログラミング言語を学ぶこと自体は、多くの人にとってアイデアを実現するための手段であると思います。

フロントエンド、バックエンド、OS以下のレイヤの各レイヤでひとつずつ得意な言語があると、アイデアを素早く実現できるようになると思います。
特に実現ハードルをおおまかに見積もることができるのが良いですが、今は難しいことが大体APIで代替できるのでそれさえも意義として薄れてきているのかもしれないです。

それでも、実際はAPIを叩いて問題が全て解決することは少なくて、DBとアプリケーションサーバ間の電気回路でいうインピーダンスマッチングをとるようなことは必要でそれなりの経験が必要だとは思います。

プロトタイプベースのオブジェクト指向言語

オライリーのステートフルJavaScriptにも書かれているように、確かにJavaScriptは開発者が必要に迫られて調べたイベント処理やDOM処理を寄せ集めた断片的でまとまりのないコードになりやすいと思います。ブロックスコープでなく関数スコープということも考慮されていないコードも多くあります。

この本ではJavaScriptがプロトタイプベースのオブジェクト指向言語であることが意識されていないことが多いと書かれています。

ここ数年はアプリの大規模化対応(言い換えるとスマホの需要急増とWEBの拡充)のためMVCフレームワークを用いた構造化プログラミングが意識されてきてるので、JavaScriptにおけるオブジェクト指向への理解が重要視されてきているのではないでしょうか。

jsonがIE8のUTF8でstringifyを使うときにエスケープされることやArray Extraの機能は知っておく価値あり。次の ES6 の仕様も決まってきているみたいです。

クラスベースのオブジェクト指向ではオブジェクトはクラス(設計図のようなもの)からインスタンス化によって実体となります。
Javascriptのようなプロトタイプベースのオブジェクト指向のプロトタイプとは、[新しいオブジェクトのコピー元となるオブジェクト]のことです。
継承元をコピーして独自のプロパティを追加していくようなイメージです。

全てのオブジェクトは一番の親となるprototypeというプロパティを持っていて、あるオブジェクトがプロパティを参照したときに、もしなければprototypeのプロパティを見る事になる。これをプロトタイプチェーンです。
ちなみにprototypeまでたどってもプロパティを持っていなければundefinedが返されます。

testConstructor.prototype.hoge= 99;

var obj = new testConstructor();
var obj_2 = new testConstructor();

obj_2.hoge = 100;

console.log(obj.hoge);// rototypeのhogeというプロパティを参照して99
console.log(obj_2.hoge);// obj_2にhogeプロパティがあるので100になる(prototypeのプロパティまで参照しない)

当然オブジェクトがプロパティを持っていれば、上記の暗黙の参照は行われることはありません。

function と Function と method

関数のオーバーロードはサポートしていません。以下のように同じ関数名で引数だけ変えることができないため、関数名は区別しなければなりません。

function showInfo(a){
  return a * 2;
}
function showInfo(b){
  return b + 2;
}

コンストラクタで関数を記述するときはダブルクォーテーションが必要となるので、読みにくい感じですが柔軟性はあります。

var hoge1 = new Function("x", "y", "return x + y");

JavaScriptは関数リテラルが使えます。こっちの方が読みやすい。

var hoge2 = function(x, y) { return x + y; };

関数とメソッドの違いだけど、プロトタイプベースのオブジェクト指向ではオブジェクトが持つ操作処理をメソッドと定義している。
ちなみにこのメソッドもオブジェクトのプロパティとなります。

連想配列の走査

for-inでハッシュ走査。Objective-CやPythonでもよく使う。

var obj = {name:'fisproject', age:25};
for(key in obj){
  console.log(key + obj[key]);
}

他にも型推測とか便利だけど、厳密性がないことによってWEBの恐さであるエンバグの発生率の高さに影響しているかもしれない。

JSONP

JSONPは JSON with Padding の略です。JSONPにおけるパディングはクロスドメインを可能にするという重要な意味を持っています。
これはjsの非同期通信で使うXMLHttpRequestにはSame-Originポリシーがあり異なるドメインにはアクセスできないためです。

ExpressでJSONPを返すAPIを作ります。
APIのresponseとしてコールバック関数名+jsonデータにしています。


// Return JSONP 
app.get('/sample.json', function(req, response){
            console.log(req.query.jsoncallback);
            var JSON = "{Anything: 1}"
            response.header('Content-Type', 'application/json');
            response.header('Charset', 'utf-8') 
            response.send(req.query.jsoncallback + "(" + JSON + ");");
}

クライアント側でURIに ?jsoncallback=? を追加します。

// this is client code
var jsonpURL = 'https://ec2-*****.ap-northeast-1.compute.amazonaws.com:****/sample.json?jsoncallback=?';
var jqxhr = $.getJSON(jsonpURL, function(data) {
     	  console.log(data); // JSONP
    });

validate.js

validate.jsは入力値をチェックできるライブラリです。
constraintsにruleを書いていく方式です。form入力のチェック等に効果的です。
有効な入力に対してはundefinedが返ってきます。

var constraints = {
  username: {
    presence: true
  },
  password: {
    presence: true,
    length: { minimum: 6, maximu: 10, message: "must be at 6-10 characters"}
  },
  age: {
    format: { pattern: "^[0-9]+", message: "must be a valid age"}
  },
  height: {
    format: { pattern: "^[0-9]+", message: "must be number" }, length: { is: 3, message: "must be at 3 numbers"}
  }
};

console.log(validate({username: "", password: "123456", age: "25", height: "168"}, constraints))
// usernameがblank
console.log(validate({username: "fisproject", password: "12345", age: "25", height: "168"}, constraints))
// passwordの文字数が足りない
console.log(validate({username: "fisproject", password: "123456", age: "ab", height: "168"}, constraints))
// ageが数字でない
console.log(validate({username: "fisproject", password: "123456", age: "25", height: "99"}, constraints))
// heightが2桁しかない
console.log(validate({username: "fisproject", password: "123456", age: "25", height: "168"}, constraints))
// undefinedなので有効な入力

validateライブラリは複数見つけたけど、 個人的に一番硬派な印象なので好きです。

[1] JavaScriptの標準仕様であるECMAScriptの歴史はこちらが詳しいです。
[2] Padding : ネットワーク通信などで、固定長データを送るときに短いデータの前や後に無意味なデータ(詰めもの)を追加して長さを合わせる処理を指します。