L'Isola di Niente
L'Isola di Niente » JavaScript Tips » JavaScript 全般の覚書

JavaScript 全般の覚書

# 最終更新日 2018.01.01

jsc {JavaScriptCore: Apple}, gjs {SpiderMonkey: Mozilla}, Node.js {V8: Google} で確認
つまり現在主要なウエブブラウザでもすべて以下の ES6 コードに対応しています

文字列操作
// console.log の Node.js でも無理矢理 print にする
if (typeof print === "undefined")
    print = console.log;


let STR = "漢字も一文字だもん!";

let a = STR.slice(3, 6);     // (開始位置 ,終了位置)
let c = STR.substring(3, 6); // (開始位置 ,終了位置)
let b = STR.substr(3, 3);    // (開始位置 ,切り出す長さ)
print(a, b, c);
//=> 一文字 一文字 一文字

print(STR.slice(3));     // (開始位置のみ指定)
//=> 一文字だもん!


// ループ(サロゲートペア対応)
for (let e of "😭😭😭") print(e);
/* =>
😭
😭
😭
*/


// 検索
print(STR.startsWith("漢字")); // 最初
//=>true
print(STR.endsWith("もん!")); // 最後
//=>true
print(STR.indexOf("も")); // 最初の出現位置、存在しなければ -1 が戻る
//=>2
print(STR.lastIndexOf("も")); // 最後の出現位置、存在しなければ -1 が戻る
//=>7
print(STR.includes("もん")); // ES6: 含まれている? (old: STR.indexOf("もん") !== -1;)
//=>true
print(STR.replace("もん", "モン")); // 変換
//=>漢字も一文字だモン!
print(STR.split("も")); // 配列化
//=>["漢字", "一文字だ", "ん!"]

print("ABCdef".toLowerCase());
//=>abcdef
print("ABCdef".toUpperCase());
//=>ABCDEF


// 前後の空白や最後の余計な改行を取り除く
let f = "  aa bb cc   \n";
print(f.trim());
//=>"aa bb cc"


// 変換
let str = "文字列をUTF-8に";
let utf8str = unescape(encodeURIComponent(str));
let utf16str = decodeURIComponent(escape(utf8str));
print(utf16str); // JavaScript 文字列は UTF-16LE

文字列と配列の変換
// 配列を文字列に
let s = ['one', 'tow', 'sex'].join(',');
// 文字列を配列に
let a = 'one tow sox'.split(' ');

配列と連想配列
if (typeof print === "undefined")
    print = console.log; 

// indexOf, lastIndexOf, includes は文字列と同様に使えます

// 配列宣言
let array = ["YAMAHA", "HONDA", "SUZUKI", "KAWASAKI"];
// 追加
array.push("MAZDA");
// 前方に追加
array.unshift("TOYOTA");
// 書き換え
array[1] = "SUBARU";
// 削除
array.splice(4, 1); // 4 番目から 1 つ分取り除く

// 要素数
print(array.length);
// ループ (ES6)
for (let s of array) {
    print(s);
}
/* output
5
TOYOTA
SUBARU
HONDA
SUZUKI
MAZDA
*/



// 連想配列、Python と同様の以下は Objects で不便。
// let map = {"TOYOTA": "LEXUS", "HONDA": "ACURA"};
// ES6 で Map が追加されたのでそちらを

let map = new Map();

// 追加
map.set("SUZUKI", "Hayabusa");
map.set("HONDA", "CBR1000RR");
map.set("YAMAHA", "XMAX");
map.set("KAWASAKI", "Z900RS");
// 書き換え
map.set("HONDA", "Super Cub");
// 削除
map.delete("YAMAHA");

// 値の取り出し
if (map.has("KAWASAKI")) {
    let n = map.size;
    let k = map.get("KAWASAKI");
    print(`${n} 個のエントリー\n${k} が含まれています`)
}

// ループ
for (let [key, val] of map) {
    print(`${key} は ${val} です`);
}
/* output
3 個のエントリー
Z900RS が含まれています
SUZUKI は Hayabusa です
HONDA は Super Cub です
KAWASAKI は Z900RS です
*/

コードポイント
// コードポイントを UNICODE 文字に変換
// Python では chr(97)
String.fromCharCode(97);
//=> 'a'

// UNICODE 文字をコードポイントに変換
// Python では ord('a')
String.charCodeAt('a');
//=> 97

即時関数
// var 宣言は他の言語と違いブロック内スコープにはなりません
// 参考: http://analogic.jp/immediate-function/
// そんな糞仕様を回避するために使われ続けてきた悲しい手段です
// ES6 で let 宣言の追加にてもはや不要、つかもう使わないでください

var func = (function () {
    // 使ってほしくないので説明はしない
}());
let, const(ES6)
// let 宣言された変数は他の言語同様にブロック内スコープになる
// var 宣言は即時実行以外はグローバルスコープになってしまう仕様
// ようするに下記のような馬鹿げたことが var では起こる
//
// 検索でよく見かける即時実行の多用はこの var の糞仕様回避のためにこうなった実例
// フレームワーク内と同じ変数名をアプリ内で使われてしまったら上書きしてしまう
// let を使うだけで無意味な即時実行をしなくてよくなるんだけど、今までがさ...

if (typeof print === "undefined")
    print = console.log; 

for (var i=0; i<=4; i++) {/*フレームワーク内で i が使われていると上書きする*/}
print(i); //=> 5 //=> ブロックスコープなんて無いから参照できてしまう

for (let j=0; j<=4; j++) {/* 他で j が定義されていても影響されない */}
print(j); //=> Error! (当然だよね)

// const は他の言語と同様に変更できない定数になる
// どうでもいいけど Swift は定数が let なのでややこしい

const ORENO_YOME = "苗ちゃん";
ORENO_YOME = "エレナ"; //=> Error

テンプレートリテラル(ES6)
if (typeof print === "undefined")
    print = console.log; 

// 普通の変数を ${} で囲んで使います
let val = "シングルクォート";

// Python の r"" 同様にエスケープシーケンスを無視するには
let raw = String.raw`この \n は改行されない`;

// ヒアドキュメントとほぼ同様
print(`バッククォートで囲みます
${val}ではありません
改行部は普通に \\n になります
${raw}`);

/* output
バッククォートで囲みます
シングルクォートではありません
改行部は普通に \n になります
この \n は改行されない
*/

メソッド定義の簡略構文(ES6)
// 一般的な Class と似たような使い方ができます
// プロトタイプと違い new は不要
// 'func1: function() {' と書けば ES5 でも使えます

if (typeof print === "undefined")
    print = console.log; 

const App = {
    _num: '666',
    func1() {
        return "Hello";
    },
    func2() {
        return this._num;
    }
}

print(App.func1());
print(App.func2());

クラス(ES6)
// クラスはプロトタイプベース継承の糖衣構文です
// なので一般的なクラスとは動作が違う場合があります
// たとえば static メンバはインスタンス化すると無効になります
// gir の継承ではコンストラクタを抜けるまで継承元が作成されない等々

if (typeof print === "undefined")
    print = console.log; 
 
class TestClassBase {
    constructor(num) {
        // コンストラクタ、メンバ変数の初期化等を行う
        this._num = num;
    }
    get num() {return this._num;}
    static staticFunc() {print("Hello");}
    instanceFunc() {print("World");}
}

class TestClass extends TestClassBase{
    constructor(num) {
        super(num);
        this._num2 = num + 3;
    }
    get num2() {return this._num2;}
    set num2(n) {this._num2 = n + 3;}
}

// static は他言語と同様
TestClass.staticFunc(); //=>Hello

const tc = new TestClass(7);
tc.instanceFunc(); //=>World

print(tc.num);  //=>7
tc.num2 = 400;
print(tc.num2); //=>403
//tc.num = 3;      // setter が定義されていないのでエラー
//tc.staticFunc(); // インスタンス化すると static 関数は呼び出しできない

非同期で実行(ES6)
// 色々な書き方があるけど非同期にしたいだけならコレが一番簡単

if (typeof print === "undefined")
    print = console.log; 

Promise.resolve(null)
    .then((value)=> {
        print("いーち");
    })
    .then((value)=> {
        print("にー");
        return "さーん";
    })
    .then((value)=> {
        print(value);
        return "だぁ!!!"
    })
    .then((value)=> {
        print(value);
    })
    .catch(function (error) {
        print(error);
    });

print("いくぞー");

/* output
いくぞー
いーち
にー
さーん
だぁ!!!
*/

8 進数, 2 進数(ES6)
// 8 進数は 0o*、2 進数は 0b* が ES6 で追加された
// 16 進数は 0x* なのは従来どおり

if (typeof print === "undefined")
    print = console.log; 

print(0o76); //=> 62
print(0b10); //=> 2
Copyright(C) sasakima-nao All rights reserved 2002 --- 2018.