「改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで」を読んでいる②

4章まで読んだ。知らない文法だけメモ。

「改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで」を読んでいる① - チョキチョキかにさん

symbol

symbolは常に一意な値を返す。enum的に使う。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol

const A = Symbol();
const B = Symbol();
A === A // true
A === B // false

Array

リテラルで初期化できる配列はArrayオブジェクト。

let array = new Array(1,2,3);

forEach

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

let array = [1,2,3];
array.forEach(function(value, index, array){
        console.log(index + ":" + value)
});

このfunctionキーワードはなんなのだろう。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions_and_function_scope

なるほど関数式。

要するに関数オブジェクトが生成されてforEachで一個ずつキックしてる感じか。Lambda式のあれみたいな感じか。

map

let array1 = [1,2,3];
let array2 = array1.map(function(value){
    return value + 1;
});
console.log(array2); // [2,3,4]

returnの値で新しい配列ができる。

some

let array = [1,2,3];
let result = array.some(function(value){
  return value === 4;
});

console.log(result)

result = array.some(function(value){
  return value === 3;
});

console.log(result)

どれかマッチしたかどうかの判定って感じ。

filter

コールバックでtrueが返った要素だけの配列を返す。

sort

let array = ["aa", "a", "aaa"];
let value = array.sort(function(x,y){
  return x.length - y.length;
})

console.log(value);

文字列でソート。

Map

  • オブジェクトと違って文字列以外をキーにできる。
  • 初期化時は要素が空。
  • Mapのキーの場合のみNaN===NaNがtrue。

キーを参照型にする場合、参照が同じじゃないとMapから値を引けない。(要するに===の結果がどうなるか。) Equals的なものはないのかな。

Set

まあなんかSetって感じ。

正規表現

let val = "1234-5678-9999";
let result = val.match(/[0-9]+/g);
console.log(result);

for(let i = 0; i < result.length; i++){
  console.log(result[i]);
}

resultにはマッチした文字列は配列で格納される。この場合gスイッチがついてるので複数マッチしてる。

マッチしてるかどうか?はRegexp.testで確認できる。

console.log(/[0-9]+/.test("abc")); // false
console.log(/[0-9]+/.test("123")); // true

マッチしてるとは?が混乱するがString.matchの結果が1件以上あるかと同義だと思えばしっくりきそう。

置換はString.replaceでできる。後方参照も使える。

Object

Objectは全てのオブジェクトの基底オブジェクト。 ここでいうオブジェクトをクラスと言っても間違いではないのだろうか。

assign

let a = {a:1, b:1};
let b = {c:2};
console.log(Object.assign({}, a, b)); // {a: 1, b: 1, c: 2}

assignの第一引数に以降のオブジェクトがマージされる。戻り値も同様の値。破壊的。

Imutable

let obj = {a:1, b:2};
Object.preventExtensions(obj); // プロパティ追加不可
Object.seal(obj); // プロパティ削除不可
Object.freeze(obj); // プロパティ変更不可

ただしstrictモードでのみ有効。

関数

関数はデフォルトでundefinedを返す。returnがあればその値を返す。

アロー関数

関数リテラルをすっきり表現できるやつという理解でいいのだろうか。

let func = (a,b) => a+b;
let val = func(1, 2);
console.log(val); // 3

関数を複数行書きたければ中括弧でくくって戻り値はreturnで返す。

function命令

function命令はコンパイル時に解析されてるので、宣言より前に呼び出せる。リテラルで初期化して値に格納する場合はあくまで値なので、その値が初期化される前に呼び出すことできない。

スコープ

変数の巻き上げ

let value = "global";
function f(){
  console.log(value); // ここでundefinedでエラー
  let value = "local";
  console.log(value);
}
f();

f関数内でのvalueの定義がなければエラーにならない。ローカル変数そのものは関数全体で有効だが、最初の出力ではまだ初期化されていないため。

ブロックスコープ

letで宣言された変数はブロックスコープになる。

let a = 1;
{    
  console.log(a);
  let a = 2;
}

巻き上げのルールは同様なのでこの場合はエラーになる。

仮引数の数

引数の数をチェックしない。足りない分はundefinedになる。

function test(a,b,c){
  console.log(a);
  console.log(b);
  console.log(c);
}

test(1); // 1, undefined, undefined

逆に仮引数がなくても引数を受け取れる。arguments経由で参照する。

引数のデフォルト

function test(a = 1){
  console.log(a);
}

test(); // 1
test(2); // 2

デフォルトは明示的に値が渡されたなかったか、undefinedが渡された場合にのみ適用される。

デフォルトがある値は後ろに宣言しないと、呼び出しが変な感じになる。(明示的にundefinedを渡してデフォルトを表現する感じになる)

// TODO オプションが複数ある場合はどうすればいいいんだろう。

必須の引数を表現

デフォルト値に例外がスローされる関数を指定しとくと必須を表現できる。めんどくさい気がしなくもない。

可変長引数

function test(...nums){
  console.log(nums);
  for(let val in nums){
    console.log(val);
  }
}
test(1,2,3);

numsは[1,2,3]になる。

function test(a, ...nums){
  console.log(nums);
  for(let val in nums){
    console.log(val);
  }
}
test(1,2,3);

この場合a=1,num=[2,3]になる。

...演算子

function test(a,b,c,d) {
  console.log(a);
  console.log(b);
  console.log(c);
  console.log(d);
}

test([1,2,3,4]); // aに配列が格納され、bcdはundefined。
test(...[1,2,3,4]); // abcdそれぞれに1,2,3,4が代入

名前付き引数

function test({a = 1, b = 2}){
  console.log(a);
  console.log(b);
}

test({a:3, b:4});

デフォルトはなくても良い。どっちかっていうとオブジェクトを渡された時それぞれのプロパティに分解する機能という理解で良さそう。

クロージャ

関数オブジェクトが参照している変数が、関数の参照が残っていると変数も確保されたままになることを利用した仕組み?

function test(arg){
    let val = arg;
    return () => ++val;
}

let a1 = test(1);
console.log(a1()); // a1の関数は参照が残る 2
console.log(a1()); // a1のスコープにあるvalも保持される 3
console.log(a1()); // なので関数が呼ばれるたびにvalのが値が増える 4

用途がわかってない。

http://d.hatena.ne.jp/artgear/20120115/1326635158

なるほど? パフォーマンスがシビアじゃない場合使わないやつくらいの認識でいいんだろか?

「改訂新版JavaScript本格入門 ~モダンスタイルによる基礎から現場での応用まで」を読んでいる①

いい加減多少まともなJSをかけるようになりたい感じがあるので読んでいる。 知らない文法だけメモ。2章まで読んだ。

Template Strings

let name = "jun";
let msg = `hello $name`;

オブジェクト

オブジェクトと連想配列は、文脈で使い分けられてるが同じものを刺している。 メソッドは関数が格納されたプロパティのことで、あくまでプロパティ。

インクリメント/デクリメント演算子

a = 1; b = 1;
a++; // 1
1
++b; // 2

この時点で変数に格納されてるのはaもbも1。

分割代入

配列

let array = [1,2,3];
let [x,y,z] = array;

x,y,zには1,2,3が代入される。

let array = [1,2,3];
let [x] = array;

xには1が代入される。

let array = [1,2,3];
let [x,...y] = array;

xには1が代入される。 yには[2,3]が代入される。

オブジェクト

let target = {a:1, b:2, c:3};
let {a, b} = target;
console.log(a); // 1
console.log(b); // 2

cは無視される。

let target = {a:1, b:2, c:{c2:3}};
let {a, b, c, c:{c2}} = target;
console.log(a); // 1
console.log(b); // 2
console.log(c); // {c2:3}
console.log(c2); // 3

子要素はこんな感じ。

delete演算子

let array = [1,2,3];
console.log(array); // [1, 2, 3]
delete(array[0]);
console.log(array); // [empty, 2, 3]

オブジェクトのプロパティも削除できる。参照が消えるが参照先のオブジェクト自体は消えない。

typeof

データ型を表す文字列を返す。配列やオブジェクトは"object"になるのでどのオブジェクトかはわからない。

for...in

let obj = {a:1, b:2}
for(let key in obj){
        console.log(key + ":" + obj[key])
}

配列の全要素にアクセスするときはlengthを格納したほうがいい

毎回プロパティにアクセスすると性能が劣化する。

for...of

let array = [1,2,3];
for(let val of array){
        console.log(val);
}

ラベル構文

test:
do{
        console.log("1")
        while(true){
                console.log("2")
            break test;
      }
      console.log("3")
}while(false)

1,2が出力される。 ただのbreakだと1,2,3が出力。

例外

try...catch...finally

try{
  let i = 1/j;
}catch(e){
  console.log(e.message); // j is not defined
}finally{
  console.log("FINALLY");
}

throw

try{
  console.log("try1");
  throw new Error("error msg");
  console.log("try2"); // 出力されない
}catch(e){
  console.log(e.message); // error msg 
}finally{
  console.log("FINALLY");
}

改元と無能について

【新元号】改元のシステム改修で慌てるシステム屋は「無能」とのこと - Qiita

とか

【新元号】改元のシステム改修で慌てるシステム屋は「無能」とのこと - Togetter

をなんとなく眺めてて話がよくわからなくなったのでなんとなく思ったことをだらだら書いてみようかなという気持ちになった

とりあえず思ったのは「みんなが完璧であることを前提に作った計画って大体破綻するんじゃね」みたいなことなんですが

「それにしてもひどすぎでしょ」みたいなことを思われるかもしれませんが 現実問題として焦ってる人がいるならそれは見積もりが甘いとしか

まずしょっぱなのツイートがあんまり理解できてなくて、

  • 30年も猶予期間ってどの期間のことだろ
  • ここでいうITってなんのことなんだろ

みたいなことを思ったんですが

ざっくりまとめると「ITの連中は30年の歴史の中でまだこの程度のことでわたわたしていてダサい」みたいな話でいいのかな 総じて無能、という話ならわからんでもない 無能の基準をどこにおくかによって人は人をいくらでも無能扱いできるので 人類は無能である

これも結局「みんなが完璧ではない」というだけ話で、ITの連中には当然賢い人もそうでもない人もいて、たくさんの人がたくさんのシステムを作ったらそりゃ考慮できてないポイントなんか無数にあるでしょという話なのかなーとか思ったんですが

しかも普通のシステムって1人だったり1つの組織がずっと管理し続けるわけじゃなくて 特定のシステムをみんなで触ったりコードを管理してる組織がコロコロ変わることなんてあるわけで

例えばデプロイのフローがやばすぎて本番にコードを反映するだけで1ヶ月かかるシステムってなくもないような気がするんですよね 流石にないかな わからんけど

こういうものを、ITじゃない会社が管理してて、「元号変わるやべーーー」ってなったときにどっかのITの会社に改修を依頼したりするパターンとかもまああるんじゃないかなと思うんですけど まあこんな極端な例じゃなくても、やばすぎてどこで何してるのかさっぱりわからないシステムの改修依頼ってあると思うんですよね

そういうものを受注したら無能、っていう話ならそれはまあわからなくはないんですけど 金いっぱいもらえるならそれを受注するのも戦略としてありなんじゃないの?と思っていて 金もらえないのにこういうの受注して現場のエンジニアが疲弊しまくってたりするならあれだなーーーーーって思うんだけど あとはなんかユーザー系の会社が親会社から頼まれて断れないとか 知らんけど

そういう会社に在籍してることが無能という話なのかな でも会社がどういう方向に舵を切るかって実際わかんなくない?って思うし いきなり社長が発狂する可能性も0じゃないし そんなサクサク転職できる人ばかりじゃないと思うし それは能力だけに限った話じゃなくて本人の環境とかも影響してくると思うし

Qiitaの記事の方もなんというか 主にコメントの方についてですが

素敵なメンバーとしか関わらなくてよくていいな〜〜〜〜〜〜〜みたいな気持ち しかし超巨大なシステムを作るときに関連メンバーが全員賢いって結構厳しくね〜〜〜〜?って思っていて みんなが完璧であることを前提に作った計画がうまく行き続けたラッキーな人なのかな とか思いつつまあ多分数人のいけてるメンバーないし個人開発をずっとしてた人なのかな〜〜〜〜という気持ち 知らんけど

問題は対策が簡単かどうかよりも対策されてないシステムがいっぱいあることだと思うんだけどな

あとそもそも他人をいちいち無能呼ばわりするの何のメリットがあるのかな〜〜〜〜っていう感覚があって

コメント欄でクソどうでもいい議論をずっとするのも無能呼ばわりしようと思えば無能呼ばわりできるし それについてクソどうでもいい文章を書くのも無能っちゃかなり無能な感じがするし

大体そんなことを考えている このようなモヤモヤをパブリックに吐き出すとその後一旦どうでもよくなる

englishbellの先生にNGマークをつけるchrome拡張

englishbellやっててどうしても合わない先生はいて、それはまあしょうがないというか合うとか合わないってあるしって感じなんだけれども

お気に入り機能はあるのにNG機能がないので、お気に入りの先生を誰も予約できなかった時に適当に先生を予約するんだが

この先生あんまり得意じゃないなーと思った記憶が消えていて、苦手な先生をもう一度予約してしまうことがあったので

履歴画面でNGをマークしとくと予約画面でわかるようにするChrome拡張を作りました。

github.com

アプリがアプリなのでwebストアには公開してないです。

Chrome拡張について