javascriptメモ

最近jsライブラリ触ることが多いので、曖昧なところを適当メモ。

無名関数

普通に定義して呼び出す。

function hoge () {
    console.log("aaaaaa");
}
hoge();

無名関数作って変数に代入して呼び出す。

var hoge = function () {
    console.log("aaaaaa");
}
hoge();

変数に代入するのも面倒な時。

(function() {
    console.log("aaaaaa");
})()

即時関数とか言われているのがこれですかね。かっこかっこ

(function($){
  $.hoge = function() { };
})(jQuery)

知ってて当然?初級者のためのJavaScriptで使う即時関数(function(){...})()の全て - 三等兵
引数渡すときは後ろの括弧に入れてあげる感じ。

オブジェクト

しかし、JavaScriptにおける「オブジェクト」の概念は、ある意味それより遥かに単純です。なぜなら、誤解を恐れずいうならば、JavaScriptオブジェクトとは、単なる「ハッシュテーブル」のようなものとして捉えることができるからです(※1)。

JavaScriptのオブジェクトとは:ちゃんと理解してますか - page2 - builder by ZDNet Japan
そーなのか。適当に生成してアクセスするテスト。

var obj = new Object();
obj.a = 10;//追加は自由
obj.b = function () {
    console.log("Hay");
}
console.log(obj.a);
obj.b();
obj["b"]();

書式(オブジェクトリテラル)を使う場合。

var obj = {
    hoge: 10,
    fuga: 20
}
console.log(obj.hoge);

forin?

そこで用いられるのが「in」演算子です。in演算子は、以下のように二通りの使い方があります。

  • オブジェクトにプロパティが存在するかどうかを判定する
  • forループとともに用い、オブジェクトのプロパティを全てループ処理する

in演算子の使用法:続JavaScriptのオブジェクトについて - builder by ZDNet Japan

オブジェクトをぶんしゃか回すためのもの?なので、foreachとは勝手が違うみたい。
foreachと同じように配列を回すのに使うと痛い目に合うかもです。(プロトタイプとかで意図した配列の要素以外のプロパティが入るとその分も回してしまうから?)

var obj = {
    hoge: 10,
    fuga: 20
}
for (var o in obj) {
    console.log(o);//=> hoge fuga
    console.log(obj[o]);//=>10 20
    console.log(obj.o);//=> undefined
}

配列

var array = [1, 2, 3, 4, 5];
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

newするより、配列リテラルでの記法がシンプルなのでそっちを使う。

  1. Cのように、値を複数格納できる「連続したメモリ領域」とはまったく違う。配列はJavaScriptオブジェクトであり、つまりハッシュテーブルである。
  2. 配列の添え字はハッシュのキーである。JavaScriptオブジェクトのキーには数値も使える事を押さえておこう(連載第3回参照)。

とても”奇妙”なJavaScriptの配列:JavaやCとは違うのだよ - builder by ZDNet Japan

変態ですね。ただ配列もjavascriptのオブジェクトなんだなって掴むとわかりやすいのかも。(認識あってるのかな)

クラスみたいななにか

function Cat () {
    //this演算子でメンバ追加
    this.old = 10;
    this.talk = function() {
        console.log(this.old.toString() + "歳だみゃー");
    }
}
var cat = new Cat();
cat.talk();

ただインスタンス事に関数オブジェクトのインスタンスを生成するのは良くないのでプロトタイプを使う。

プロトタイプとは、以下のような特徴を持つオブジェクトです。

  • プロトタイプの実体は、コンストラクタ関数が持つprototypeプロパティ
  • 同じコンストラクタを持つオブジェクト間で共有される
  • オブジェクトのメンバを参照すると、「オブジェクト→オブジェクトのプロトタイプ」の順で検索される

JavaScriptのオブジェクト指向:プロトタイプをきちんと理解する - page2 - builder by ZDNet Japan

プロトタイプを使った例。

function Cat () {
    //this演算子でメンバ追加
    this.old = 10;
}
Cat.prototype.talk = function() {
    console.log(this.old.toString() + "歳だみゃー");
}
var cat = new Cat();
cat.talk();

匿名関数とセットで。

var Cat = (function() {
    function Cat () {
        //this演算子でメンバ追加
        this.old = 10;
    }
    Cat.prototype.talk = function() {
        console.log(this.old.toString() + "歳だみゃー");
    }
    return Cat;
})();
var cat = new Cat();
cat.talk();

プロトタイプチェーン

javascriptはメンバをオブジェクト→オブジェクトのプロトタイプと探す。プロトタイプもオブジェクトなので連鎖する。最終的にObjectのプロトタイプまで検索すると停止。
プロトタイプに他のクラスのインスタンスを代入することで継承が実現できる。

thisさんの憂鬱

入れ子関数の場合。thisがグローバルを指してしまう。

var Cat = (function() {
    function Cat () {
        //this演算子でメンバ追加
        this.old = 10;
    }
    Cat.prototype.talk = function() {
        console.log(this.old.toString() + "歳だみゃー");
        var self = this;//バインディングしてあげないといけない
        function talk2 () {
            var saba = self.old / 2;
            console.log(saba.toString() + "歳だみゃー");
        }
        talk2();
    }
    return Cat;
})();

ブロックスコープ

javascriptにはブロックスコープがないようです

var x = 0;
{
    var x = 2;
}
console.log(x);//=> 2

だから擬似的に?スコープを作れる無名関数が使われるわけかな。