くろねこ日記

ソフトウェアに関する技術メモが多いです.

JavaScript勉強しました

はじめに

Django,Flaskなどのウェブフレームワークを使う上で,実情ではJavaScriptの存在は欠かすことができません.

僕はJavaScriptの知識が殆どないため,そこがネックでした.

なので,ここ2日ほど合間を縫って勉強してみました.

今日はそのメモを載せておきます.

参考にしたページ

JavaScript ガイド - JavaScript | MDN

まずはこのページを読んで勉強しました.1番から9番ほどまで手を動かしつつ進めました. このページのおかげで,JavaScript独特のスコープの考え方,オブジェクト指向をある程度把握することができます.

最近の行儀のよい JavaScript の書き方 - Qiita

JSは本当に多用な書き方ができます.それにゆえに,質の悪いコードを作りがちです. このページではJSを書く上で綺麗に書くための方法が示されており,個人的には非常に助かりました.

JavaScript勉強中のメモ

主に以上の二つのページを参考にして勉強しました. この中で個人的にひっかかった部分をメモしておこうと思います.

弱い型

JSは弱い型付き動的言語として知られています. 弱い型とは文字列と整数の評価が曖昧なことです.

例えばPythonでは

print(1=='1') # false

リテラルの違いによりfalseが表示されます. JSでは

console.log(1=='1'); // true

とすると評価が曖昧なのでtrueが返ってきます.

ただし,

console.log(1==='1'); // false

のようにイコールを3つ並べると厳密な判定をするようになるので,falseが返ってくるようになります. ですので,こちらのイコールを3つ並べるような使い方のほうがバグは起きにくいと思います.

ちなみに

1+'1'

では11という結果が返ってきます.文字列を優先的に識別しているみたいですね(型変換しなくて良いので楽かも).

ホイスティング

JSでは変数を定義した位置関係なく呼び出せるような仕組みがあります. これをホイスティングと呼びます.

実際にホイスティングの例を示します.

まずは変数が無いとエラーを吐くコードを書いてみます.

console.log(foo); // error

このコードはxが定義されていないので当然エラーが出ますね.

では次のように書いた場合ですと

console.log(foo); // undefined
var foo;

undefinedと表示されます つまりfooという変数が評価される文の後に定義した場合でもホイスティングによって

var foo;
console.log(foo);
foo;

と同じコードを意味するようになります. つまり,うっかり変数を比較などする部分を変数宣言の前に書いてしまうと エラーを吐かないということでちょっと怖いですね.

綺麗なJSコードまとめ

先程,紹介したリンクのうちの「最近の行儀のよいJavaScriptの書き方」でもわかりやすくまとまっているのですが,初心者にとっては理解が難しい箇所があったのでそこを補足する形になりますがメモしておきます.

無名関数の書き方の意味

まず以下のようにして書く無名関数が呪文にしか見えませんでした.

(function() {
    //処理
})();

これをわかりやすく理解するためにメモしておきます.

まず

foo = function(){
    //処理
}
foo();

これはfooに無名関数を代入してますね. foo()で実行してますね. でもfooに代入しないで自身で実行までするようにコードを書いてみます.

function(){
    //処理
}();

最後に()をつけることで実行しようとしているのですが,こうするとエラーがでちゃいます. そこでfunction全体を小括弧で括ってから実行してみますと,自然と次のような書き方になります.

(function(){
    //処理
})();

これで無名関数がなぜこのように書くのかについて把握できたかなと思います.

あとは記事を読めばわかりやすいかなとは思います.

個人的に気になったのはメンバ変数にどうやって外部からアクセスするかです. それ以外の詳細は本記事で参考にしたブログを読んでもらえればと思います.

たとえば,fooという変数をpublicなメンバ変数として扱いたい場合とします. ただし,hamという変数はprivateにしたいとします.

その場合は,publicなメンバ変数をfooコンストラクタの中にthisをつけてfooを書けば良いです. pribateな場合はthisをつける必要はありません.

(function(global){
    "use strict";
    var ham = null;
    function MyClass(b){
        this.foo = null;
        ham = b;
    }
    MyClass.prototype.hello = MyClass_hello;

    function MyClass_hello(name){
        console.log("Hello "+ name);
        console.log("foo "+ this.foo);
        console.log("ham "+ ham);
    }
    
    global.MyClass = MyClass;

})((this || e).self || global);

mycl = new MyClass("hi"); // ham = "hi", this.foo = null
mycl.foo = "foo"; // ham = "hi", this.foo = "foo"
mycl.ham = "egg" // hamにeggは代入されない(Errorは特に出ないけど)
mycl.hello("kuroneko"); 

出力

"Hello kuroneko"
"foo foo"
"ham hi"

です.

まとめ

JavaScriptで詰ったところについてまとめました.

勉強するにあたり,Twitter上で@mkamimuraさんには御助言を頂く機会があり,助かりました. ありがとうございました!