20210225のJavaScriptに関する記事は20件です。

JavaScriptでHTMLを取得する方法

JavaScriptでHTMLを取得する

まず、大きく方法は3種類あります。
・id名から取得する方法
・class名から取得する方法
・セレクタ名から取得する方法

これからそれぞれの方法でHTMLの取得方法を説明します。

 id名から取得する方法

STEP1
HTMLの取得したい要素に「 id 」を設定

<div class="〇〇" id="〇〇"></div>

STEP2
getElementByIdというメソッドを使います。

document.getElementById("id名")

 class名から取得する方法

getElementsByClassNameというメソッドを使う。classの中に要素が複数あってもすべて取得することができます。

document.getElementsByClassName("class名")

 セレクタ名から取得する方法

querySelectorAllメソッドを使う。指定したセレクタ名に合致するものをすべて取得します。

document.querySelectorAll("セレクタ名")

また、指定したセレクタに合致する要素のうち一番最初に見つかった要素1つを取得することもできます。querySelectorメソッドを使います。頻繁に使用するセレクタ名として、class名、id名、HTMLタグがある。class名は(".class名")、id名は("#id名")、HTMLタグは("タグ名")と表記する。

document.querySelector("セレクタ名")

【 補足 】
Q.セレクタ名とは?
➟CSSでスタイルを適用するために指定している要素

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

javascript 配列を操作するメソッド

javascriptにおいて配列を操作するメソッドです。

1. forEachメソッド

  • forEachメソッドとは、要素を1つずつ取り出して、全てに繰り返し処理を行うメソッドです。
example.js
const numbers = [1,2,3];
console.log(numbers);
//出力結果 [1,2,3]

numbers.forEach((number) => {
  console.log(number);
});
//  出力結果
//  1
//  2
//  3

という結果になります。

example.js
numbers.forEach((number) => {
  console.log(number);
});

こちらの記述に注目します。
このように引数に関数を入れたものをコールバック関数と呼びます。
コールバックとは関数の中に違う関数を入れて関数を呼びだすための関数を指定することです。

2. pushメソッド

  • pushメソッドとは、配列の最後に新しく要素を追加できるメソッドです。
example.js
const numbers = [1,2,3];
console.log(numbers);
//出力結果 [1,2,3]

numbers.push(4);
console.log(numbers);
//出力結果 [1,2,3,4]

という結果になります。
ここは問題ないかと思います。

3. findメソッド

  • findメソッドとは、条件式に合致した最初の要素だけを取り出すメソッドです。
example.js
const numbers = [1,2,3];
console.log(numbers);
//出力結果 [1,2,3]

const evenNumber = numbers.find((number) => {
  return number % 2 === 0;
});
console.log(evenNumber);
//出力結果 2

という結果になります。
こちらでもコールバック関数が使われています。
number % 2 === 0は、とある値を2で割った余りが0。
すなわち偶数を条件としています。
そして、順番に条件を当てはめていき、最初に当たった数字が2なので、出力される値は2となります。
注意としては、returnを使用して、処理を終了させましょう。

4. filterメソッド

  • filterメソッドとは、条件式に合致した要素を全て取り出すメソッドです。
example.js
const numbers = [1,2,3];
console.log(numbers);
//出力結果 [1,2,3]

const oddNumber = numbers.filter((number) => {
  return number % 2 !== 0;
});
console.log(oddNumber);
//出力結果 [1,3]

という結果になります。
こちらでもコールバック関数が使われています。
また、find同様returnを使用して、処理を終了させましょう。

number % 2 !== 0は、とある値を2で割った余りが0ではないもの。
すなわち奇数を条件としています。
そして、順番に条件を当てはめていき、当たった数字が1と3なので、出力される値は[1,3]となります。

5. mapメソッド

  • mapメソッドとは、配列の要素全てに処理を行い、新しい配列を作り出すメソッドです。
example.js
const numbers = [1,2,3];
console.log(numbers);
//出力結果 [1,2,3]

const tripleNumber = numbers.map((number) => {
  return number * 3;
});
console.log(tripleNumber);
//出力結果 [3,6,9]

という結果になります。
こちらでもコールバック関数が使われています。
また、find,filter同様returnを使用して、処理を終了させましょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptについて考える静的型付け言語と、動的型付け言語について

主題

本記事は、JavaScriptについて考える静的型付け言語と、動的型付け言語についてまとめたみたものです。

まずそれぞれの型についてまとめる前に、
「二進数」
「16進数」
について簡単にまとめました。

二進法について

コンピュータが扱うデータは全て二進数で表現できます。0と1だけであらゆる「情報」を表現できるのです。数値は勿論、画像や文字も0と1の二進数で表現できます。

16進数について

2進数には 0と1の2種類の数字で表現しましたが、16進数には 16種類の数字があります。 文字としての数字は 0 から 9 までの 10種類しかないので、 アルファベットの A ~ F を 「数字」 として借用します。
16進数は 0 から F までの 16種類の数字を使って数を表し、 数が 0 から 1、2、3… と順に増えていくとき、7、8、9 の次は A、B、C と続き、 D、E、F までは 1桁ですが、 次に桁上がりして 10 になります。

// 例の記載
0, 1, 2 .. d, e, f, 10, 11, 12 … 1d, 1e, 1f, 20, 21, 22 ... 2d, 2e, 2f, 30

コンピュータ等の内部では 2進数が使われていますが、その内部の状態などを表示する
際に 2 進数は余り使われていません。これは、2 進数で表示すると桁数が多くなる上、0 と
1 だけが繰り返される 2 進数の列は専門家でも読みにくいものとなってしまいます。このた
め、一般的には 16 進数というものが使われています。

数値

二進数で1桁の場合、0 1 の 2通り(2^1 )
二進数で2桁の場合、00 01 10 11 の 4通り(2^2)
二進数で3桁の場合、000 001 010 011 100 101 110 111 の 8通り(2^3)

二進数で8桁の場合、00000000 00000001 ... 11111110 11111111 の (256通り 2^8)

かなり桁数が多くなってしまいます。

光の三原色 RGB(red、green、blue) の光の強さを それぞれ 0-255 で表現することで1677万色 を表現できます (256 x 256 x 256 = 16777216)

二進数表記だと見辛いため、CSSなどでは 16進数 で表記されることが多いです。

#00ff00 // 2進数だと 00000000 11111111 00000000 となる
#ffffff //  2進数だと 11111111 11111111 11111111 となる

文字

例えば、
Unicode、ASCIIコード、Shift-JIS、UTF-8

これら世界中の文字を集めたデータがあり、文字ひとつひとつにコードが割り当てられています。
https://wa3.i-3-i.info/word1812.html

以上の事をふまえて・・・

このように全部01などの数値でデータにするとコンピューターが何のデータか分からないという事が発生します。

例えば 0011010100100111 という並びのデータがあるとき、このデータが数値を表すのか、色を表すのか、文字コードを表すのか分かりません。もしデータに対する型があればコンピュータがその数値をどのように解釈すれば良いか分かります。

なのでどんな型なのかをコンピュータへ伝えることは大事ということになります。

JavaScriptにおけるデータ型について

結論として、JavaScript は動的型付け言語です。

プログラミング言語には大きく分けて静的型付け言語と、動的型付け言語の二種類があります。
「型付け」「型」とは?動的と静的の違いは?

動的型付け言語は型(=変数に入るデータの種類)を指定しないで変数を使用できます

JavaScriptとJavaで変数を宣言するコードを比較してみましょう。
(JavaScriptとJavaは全く別の言語です。食べ物のハムとハムスターくらい違います。)

JavaScript(動的型付け言語)の変数宣言

var str = "Hello" // string型
var i = 1 // number型
var f = 1.1 // number型
var bool = true // boolean型

Java(静的型付け言語)の変数宣言

String str = "Hello"; // String型
int i = 1; // int型
float f = 1e-1f; // 1×10^-1 float型
double d = 1.0; // double型
boolean b = true; // boolean型

動的型付け言語では、プログラマは型を意識しないで変数を使用できます。一方、静的型付け言語の場合、変数にどんな値が入るかプログラマが指定する必要があります。

静的型付け言語の場合、は指定した型と違うデータが入ってくると、エラーが発生します。
動的型付け言語の場合は、エラーが発生しません。

デメリットについて

上記のように書くと、動的型にはメリットしかないと思ってしまいますが、そうでもありません。

プログラムを実行しないとバグがわからない

事前に分からないため、リリースしたあとに結構気がついたりすることが起きます。

無駄なメモリが発生する

必要なメモリ数が把握できないので、余分に多くメモリ領域を取っておく等しておかないといけません。

型とは

変数に入るデータの種類(文字列なのか、数値なのか、真偽値なのか…etc)を表す。

JavaScriptで使えるデータ型一覧

JavaScriptにはプリミティブ型のデータ型7つ+オブジェクトというデータ型があります。

プリミティブ型

Boolean
- 真偽値。true または false
Number
- 数値。整数または浮動小数点数。例えば 423.14
BigInt
- 長整数。精度が自由な整数値。例えば 9007199254740992n など。
String
- 文字列。テキストの値を表す連続した文字。"Hello" など。
Symbol
- シンボル。インスタンスが固有で不変となるデータ型。
null
- null 値を意味する特殊なキーワード。JavaScript では大文字・小文字を区別するので、nullNullNULL などとは異なる。
undefined
- 未定義。値が未定義の最上位プロパティです。

オブジェクト型

Object
名前と値をもつプロパティを格納する入れ物

typeof演算子

宣言した変数がどんな型なのか確認できます。

var a
typeof a
// "undefined"

var hoge = true
typeof hoge
// "boolean"

var fuga = 100
typeof fuga
// "number"

var hage = 100000000000000n
typeof hage
// "bigint"

var obj = {}
typeof obj
// "object"

まとめ

  • JavaScriptは動的型付け言語
  • JavaScriptにはプリミティブ型のデータ型7つ+オブジェクトというデータ型がある
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptの関数とメソッドの違いとは?

JavaScriptを始めたばかりの初学者にとっては、両者の違いは分かりづらいものです。

どちらも引数を入れたり、戻り値を返してくれたりと似通っているため、見分けが付け辛いですよね。

またやってること自体もそんなに差はないのです。

ただ概念として違います。

関数とは?

関数とはいくつかの処理がまとまったブロックのことを言います。

console.log("こんにちは");
console.log("Hello");
console.log("Guten Tag");
console.log("ニーハオ");

何度も繰り返し同じ処理を行うとき、同じ処理を繰り返し使うというのはメンドクサイものです。

そこで関数があると便利なわけです。

const greet = function() {
console.log("こんにちは");
console.log("Hello");
console.log("Guten Tag");
console.log("ニーハオ");
};
greet(); //関数の呼び出し

一度関数として設定しておけば、定義する際に使用した定数名greet();と書くだけなので楽です。

メソッドとは?

メソッドとは、オブジェクトに属する処理や操作のことをメソッドと呼びます。

メソッド名(){}とすることで定義できます。

メソッド名(){
// 行いたい処理
}

関数とメソッドの違いとは?

オブジェクトの中で定義されているかどうかというのが主な違いになります。

オブジェクトの中で定義されていれば、メソッド。
そうでなければ関数です。

JavaScriptは、お互いに関連するデータの集合とそれらに対する手続き群をひとまとめにした「オブジェクト」をプログラムの基本的な構成単位として扱うことから、オブジェクト指向プログラミング言語と呼ばれているのです。

クラスやプロトタイプ。
メソッドやプロパティを定義する構文。
オブジェクトのインスタンス化についても、しっかり理解を深めておく必要があります。

この記事のまとめ

以上、初投稿ということで、めちゃめちゃ短くシンプルにまとめさせていただきました。

まだよく使い方も分かっておりませんが、投稿を継続していこうと思っています。

エンジニアの方。

もし私の記事を読んで「そこちゃうやろ!」と思ったら、ガンガン言ってきていただければ。。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

変数・定数・関数宣言方法

変数の書き方

const testScope = (scope) => {
  if (scope === 'block') {
    let message = 'ブロックスコープ'
    console.log(message)
  }
  // console.log(message)//letの場合ブロック内{}のみ参照可能
//よってこちらはエラーになります
//ReferenceError: message is not defined 
}
testScope('block')

let mutableText = 'let変更前';
mutableText = 'let変更後';  //再代入可能
console.log(mutableText);

定数の書き方

const immutableText = 'const変更前';
immutableText = 'const変更後' //再代入不可
console.log(immutableText);

const mutableArray = [1,2,3];
mutableArray.push(4)
console.log(mutableArray);//結果[1,2,3,4]
配列やオブジェクトは定数宣言しても変更可能

const mutableObject = {id: 'hoge', value: 'fuga'}
mutableObject['name'] = 'bar'
console.log(mutableObject)
//結果 
Object {
  id: "hoge",
  name: "bar",
  value: "fuga"
}

アロー関数の書き方

function nameFunc(message){
  console.log(message)
}

nameFunc('これは名前付き関数です')

const arrowFunc = (message) => {
  console.log(message)
}

arrowFunc('これはアロー関数です')

const oneLineArrowFunc = (message) => console.log(message);
oneLineArrowFunc('これは1行で書いたアロー関数です')

const users = {
  hoge: 'Hallo Bob' //hogeというユーザーIDはHallo Bobというユーザーネームを持っている
}
const getUsername = (userId) =>{
  return users[userId]; //returnを省略できる
} 
const username = getUsername('hoge')
console.log(username)


getUsernameという関数を実行
getUsernameにはhogeという文字列を渡した
関数の中でhogeがuserIdとして引数で渡されて
usersっていうオブジェクトのhogeというキーの値を返すという形になります。
usersのhogeというキーはvalueはHallo Bob

ざっくりですが復習しました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Web API

XMLの利用

getElementsByTagName()
getAttribute()

JSONの利用

Request → Respnse.json() → data

リスト:[]
→要素数を指定してあげる。先頭のデータなら[0]をつける
辞書:{}
→ドットでつなぐ

JavaScriptでの利用方法

1 . fetch
2 . axios
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【JavaScript】 海外Teck系YouTuberを真似てみた! BookList App | No Frameworks

1,はじめに

この記事は、海外Teck系YouTuberの動画を参考に、同じプロジェクトを作成してみたものになります!
簡単にですが、動画を通して学べた技術や知識をまとめました!

2,学んだこと

Frameworksを使わずに、BookListを作ることができました!
主に、

① classの作成
② static メソッドの作り方と使い方
③ localStorageの追加と削除

BootswatchFont Awesomeも使いながら、デザインについても学ぶことができました!

3,参考動画

IMAGE ALT TEXT HERE
YouTube: https://youtu.be/JaMCxVWtW58

4,完成:tada:

2021-02-25_16h47_16.gif

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Promiseで配列を逐次処理する

Promise で配列を逐次処理する

Promiseを再帰的に呼び出すことで配列を逐次処理します、配列を元にWEBAPIを1回ずつ呼び出す必要があり作成に至りました。
ソースコード内 sequentialPromise 関数が逐次呼出しする関数です、sequentialPromiseSub をAJAX等でAPI呼び出しする関数に置き換えて考えれば使用用途がわかりやすいかと思います。

<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="Pragma" content="no-cache">
        <meta http-equiv="Cache-Control" content="no-cache">
        <title>
            テスト
        </title>
    </head>

    <body>
        <button id="button1" type="button">
            ボタン1
        </button>

        <div id="view">
        </div>
    </body>

    <script type="text/javascript">
        function TestClass() {
            var self = this;
            self.sequentialPromiseSub = function(value) {
                var me = this;
                console.log("value", value);
                document.getElementById("view").textContent = "value = " + value;
                return new Promise(function(resolve) {
                    setTimeout(function() {
                        resolve(true);
                    }, 1000);
                });
            }
            self.sequentialPromise = function(array) {
                var me = this;
                if(array.length == 0) {
                    return Promise.resolve(true);
                }
                var value = array.shift();
                return me.sequentialPromiseSub(value)
                .then(function() {
                    return me.sequentialPromise(array);
                });
            }
            self.setupEvent = function() {
                var me = this;
                var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
                document.getElementById("button1").addEventListener("click", function() {
                    console.log("button click");
                    me.sequentialPromise(array)
                    .then(function(result) {
                        console.log("result", result);
                        return true;
                    });
                });
            }
            self.setupEvent();
        }
        var obj = new TestClass();
    </script>

</html>

Promise.all じゃだめなのか

Promise.allだと並列に一斉にWEBAPIを呼んでしまい100個とか数が多かった場合にAPIが1,2個失敗しました、API側の環境を改善しろという話なのかもしれませんが呼び出し側で対応した結果こうなりました。
珍しい使い方のように思えたので記事にしました、以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Node.js】日時処理を扱う方法

プログラミング勉強日記

2021年2月25日

日付処理を使うための準備

 Node.jsで日付処理を扱うために、今回はdate-utilsを使用する。
 date-utilsはnpmパッケージの1つで、簡単にインストールすることができる。

date-utilsをインストールする
$ npm install date-utils

現在時刻を表示する

// date-utilsを呼び出す
require('date-utils');
let now = new Date();
console.log(now.toFormat('YYYY年MM月DD日 HH24時MI分SS秒'));
console.log(now.toFormat('YY年M月D日 H時MI分SS秒'));
console.log(now.toFormat('DDD MMM DD YYYY HH24:MI:SS'));
console.log(now.toFormat('M/D/YY'));
実行結果
2021年02月25日 01時52分13秒
21年2月25日 1時52分13秒
Thu Feb 25 2021 01:52:13
2/25/21

参考文献

日付に関する実装!Node.jsで書くDateの使い方【初心者向け】

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Node.js セキュリティアップデート + Node.js v15 について

Node.js セキュリティアップデートが出てた

https://nodejs.org/en/

2.23 に、Node.js の新しいバージョンがでたのでチェックしよう。
https://nodejs.org/en/blog/vulnerability/february-2021-security-releases/

10.x, 12.x, 14.x 15.x 用のセキュリティアップデート

重大(1), 高い深刻度(1), 低い深刻度(1)

  1. HTTP/2 の unknownProtocol があまりにも多くなった時、DoS 攻撃を受ける可能性がある問題
    • ファイルシステムが漏洩する可能性
    • メモリリークを引き起こす可能性
  2. localhost6 がホワイトリストに含まれている場合、DoS 攻撃を受ける可能性がある問題
  3. OpenSSL の脆弱性が Node.js を介して悪用される可能性がある問題

適宜追従しましょう(フロントエンドだけなら別にって感じだけど)。

Nodejs 10.x は 2021.4.30 にサポート終了予定、12.x 系は 2022.4.30 で終了予定
※奇数バージョンは機能開発用バージョンで、偶数バージョンは長期サポートバージョン。最新 15.x 以外の奇数はない

Node.js のバグ報告について

nodejs-sec グループ
https://groups.google.com/g/nodejs-sec?pli=1

バグ報告の方法
https://github.com/nodejs/node/blob/master/SECURITY.md

Nodejs にバグを報告するとお金もらえるプログラム:バグバウンティプログラム
https://hackerone.com/nodejs


Node.js v15 について

Node.js v15 あまりキャッチアップしてなかったので、おさらいしてみました。

https://nodejs.org/en/

v15 のリリースは 2020.10.21。v16 は 2021.4 とかですかね。

公式 Medium
https://nodejs.medium.com/node-js-v15-0-0-is-here-deb00750f278

codedamn さんのまとめ YouTube
https://www.youtube.com/watch?v=OIzGI5wFiXg

めっちゃまとまってる
https://shisama.hatenablog.com/entry/2020/10/21/004612

1. npm 7 が同梱

npm 7 が入った。

https://www.npmjs.com/package/npm

  • workspace という概念が入った
    • monorepo で作りたい時とかは便利そう
  • acceptDependencies という概念も入った
  • peerDependencies の挙動変更
  • npx が実行前に確認されるようになった
  • npm audit の表示方法が変更
  • package.exports が npm の内部モジュールを参照できないようになった
  • npm test の表示内容が変更
  • npm buildnpm unbuild が廃止

https://blog.watilde.com/2020/10/14/npm-v7の主な変更点まとめ/

2. unhandledRejection の挙動変更

ブレイキングチェンジ!

  • unhandledRejection の挙動が変わった。default warn だったのが throw になった。

ただそもそもこれが起きてる時は以下のタイミングで

  • Promise を使った非同期処理において想定外のエラーが起きた
  • エラーハンドリングが漏れている
  • 単純なコードのエラー

マズイプログラムになっているはずなので、挙動が変更になることでより安全なコードが書けるようになった。

https://zenn.dev/kimamula/articles/b32d11d52c2b7a733119

unhandledRejection について

https://medium.com/@hagevvashi/unhandledrejectionについて-70739d2b6a60

Web サービスを運営していると、Sentry を使ってエラーハンドリングしたりすると思う

https://sentry.io/welcome/

window.onerror は、Promise.reject() によって投げられたエラーは拾わない
(ただし console.error() 形式で表示はされる)

Promise を使うエラー(Node.js でファイル操作だとかをするときの I/O 処理や、ブラウザで API 通信の失敗)を検知する時に使う。

try {
  await axios.post("/some-resources");
} catch(e) {
  // error handling
  throw e; // this causes unhandled rejection
}
window.addEventListener("unhandledrejection", (e: PromiseRejectionEvent): void => {
  // an error loginng
  logError(e.reason);
});
process.on("unhandledRejection", (error: {} | null | undefined, promise: Promise<any>) => {
  // an error loging
  logError(error);
})

https://medium.com/@hagevvashi/unhandledrejectionについて-70739d2b6a60

3. ES2021 に対応

JavaScript エンジンの V8 が v8.6 にアップデート。まぁでもブラウザでは既に使えるので珍しくはない

Promise.any

Promise.all は、全部が resolved になった時 / どれかが rejected になった時エラー

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, 'foo');
});

Promise.all([promise1, promise2, promise3])
  .then((values) => {
    console.log(values);
  })
  .catch(() => {
    console.log("error");
  });
// expected output: Array [3, 42, "foo"]

Promise.race は、どれかが resolved になった時 / どれかが rejected になった時エラー
Promise.allSettled は、全部が resolvedrejected になった時 / エラーにはならない
Promise.any は、どれかが resolved になった時 / 全部が rejected になった時エラー

10 個の Promise を走らせて、9 個失敗しても、最後の 1 つが成功なら成功としたい時(race だとどれかが reject になるとエラーになっちゃう)に使う

WeakRefs

Garbage Collection 時に破棄できるオブジェクトを作れる。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef

var ref = new WeakRef(element)
ref.deref() // 参照元を取り出す

簡単にサンプルを作ってみた。↓
https://playcode.io/740665/

タイマーが動き続けている。別のタイマーで DOM 要素を 5 秒後に remove する。元のタイマー関数では参照はできている。Garbage Collection されると参照がきえて止まる。

メモリリークを防ぐコードが書ける。

AggregateError

複数のエラーをまとめたい時に使う。

try {
  throw new AggregateError([
    new Error("some error"),
  ], 'Hello');
} catch (e) {
  console.log(e instanceof AggregateError); // true
  console.log(e.message);                   // "Hello"
  console.log(e.name);                      // "AggregateError"
  console.log(e.errors);                    // [ Error: "some error" ]
}

エラーを配列で与えられる。

Logical Assignment Operators 論理代入演算子

読みにくくなるからやめてほしいw

let a = true
a &&= false // x && (x = y): x と y が true な値の場合、y の値が代入される
// false
a
// false
a ||= true // x || (x = y): x が false な値の場合、y の値が代入される
// true
a
// true
a = null
a ??= 1 // x ?? (x = y): x が null or undefined な値の場合、y の値が代入される
// 1
a
// 1
a ??= 2
// 1
a
// 1

Numeric separators

桁が読みやすくなるから積極的に使おう。

123 === 1_2_3
// true
1_000_000_000.000_001
// 1000000000.000001

ただこんなでかいマジックナンバー扱いたくないし扱う機会もない気がする。

String.prototype.replaceAll

ブラウザで使えるようになってたやつ。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
https://caniuse.com/mdn-javascript_builtins_string_replaceall

IE 11 は Babel を通せば replaceAll が書かれたコードはトランスパイルしてくれる。preset-env (core-js) を使うことで IE11 でも動く。

https://v8.dev/features/string-replaceall

ちなみに Next.js は @babel/preset-env 入ってないので IE11 対応させるなら config で指定する。

4. Web Crypto API

JavaScript で暗号化・復号・署名・検証ができる Web 標準 API。

https://caniuse.com/cryptography

ブラウザでは昔っから使えたやつ。
Node は最近ブラウザで使えたやつが使えるようになってきているといういい話。

5. AbortController

Web リクエストを中止することができるグローバルユーティリティオブジェクトの AbortController が Node.js 15 でも使えるようになった。

const ac = new AbortController();
ac.signal.addEventListener('abort', () => console.log('Aborted!'),
{ once: true });
ac.abort();
console.log(ac.signal.aborted);  // Prints True

動画のダウンロードを中止する例

https://developer.mozilla.org/en-US/docs/Web/API/AbortController

var controller = new AbortController();
var signal = controller.signal;

var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchVideo);

abortBtn.addEventListener('click', function() {
  controller.abort();
  console.log('Download aborted');
});

function fetchVideo() {
  ...
  fetch(url, {signal}).then(function(response) {
    ...
  }).catch(function(e) {
    reports.textContent = 'Download error: ' + e.message;
  })
}

fetch はまだ Node.js に実装されてないけどね。

フロントエンドの UI 開発で、ボタンに対しての mousedown/mouseup イベントを addEventListen していて、クリック後画面遷移してしまうので removeEventListen しておきたい時、abortController を使えば一発で解除できるテクがどっかで紹介された。

6. Event Target

ブラウザで使えた EventTarget が Node.js でも使えるようになった。Event の発行・伝播はブラウザでは EventTarget、Node.js では EventEmitter を使っていた。

https://nodejs.org/api/events.html#events_eventtarget_and_event_api

const target = new EventTarget();

target.addEventListener("foo", (event) => {
  console.log("foo is called");
});

const ev = new Event("foo");
target.dispatchEvent(ev);

イベントが DOM ツリーを伝って伝播が行われないなど差はあるが、ユニバーサルなプログラムが書けるようになってきている。

7. N-API updated

Node.js のネイティブ拡張をするための Node API (通称 N-API) がアップデート。C 言語のインターフェース。まぁ使うことはあまりないのかなぁ。

https://nodejs.org/api/n-api.html#n_api_node_api

8. QUIC (実験的機能)

UDP ベースの通信プロトコル「QUIC」が使用できるようになった。
TLS 1.3 ベースでのセキュリティ、フロー制御、エラー訂正、接続、多重化とかとか。

TLS 1.3 とは: https://kinsta.com/jp/blog/tls-1-3/

HTTP/3 サーバーを作ることができる。
https://blog.leko.jp/post/http-over-quic-on-nodejs15/

むずすぎてよくわからんですね

かんそう

  • せめて Node.js 14.x にはしとこう
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScriptで String (文字列) を昇順 (asc)・降順 (desc) にソートする

はじめに:

やりたいこと

JS で 文字列 (String) をソートしたい。
・ "627118" -> (昇順) -> "112678"
・ "627118" -> (降順) -> "876211"
・ "Hello World" -> (昇順) -> " HWdellloor"
・ "Hello World" -> (降順) -> "roollledWH "

考察

昇順ソート

・String => 1文字1文字を配列にする (str.split('')) => sort() => 配列から文字列に戻す (strArr.join('')) 

降順ソート

・上記にプラスして、sort() の後に reverse()

やったこと

/**
 * @param {String} str
 * @return {String}
 */
function sortAsc(str){
    // 各文字を区切って、配列に変換
    let strArr = str.split('');
    // 昇順
    strArr.sort();
    // 配列を文字列に戻す
    return strArr.join('');
}
/**
 * @param {String} str
 * @return {String}
 */
function sortDesc(str){
    // 各文字を区切って、配列に変換
    let strArr = str.split('');
    // 昇順
    strArr.sort();
    // 降順
    strArr.reverse();
    // 配列を文字列に戻す
    return strArr.join('');
}

結果

sortAsc("627118"); // 112678
sortDesc("627118"); // 876211
sortAsc("Hello, World"); // " HWdellloor"
sortDesc("Hello, World"); // "roollledWH "

終わりに

もっと早いやり方あれば、コメントください。ありがとうございました。

関連記事:

Java で String (文字列) を昇順 (asc)・降順 (desc) にソートする

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

readonlyしてないのにreadonlyエラー

なんでだろう

interface UserModel {
    name: string;
}
const newUser = Object.create(UserModel);
newUser.name = 'xxx' // ←TypeError: "name" is read-only

調べてわかったこと

  • JavaScript組み込みオブジェクトのFunctionにnameという名の 「読み取り専用」プロパティがある
         ↓
  • TypeScriptの言語的な特性上、その読み取り専用のプロパティに代入しようとしたと 判断されてしまった?

どう対応したか

  • UserModelのnameをuserNameに変更しました。

・・・ほかにも方法があったのか、詳しい人いたら教えてくださいまし m(__)m

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

文字列連結時、大量の場合➡効率について

文字列連結時、大量の場合➡効率について、以下は参考になります。

sample.js
//効率悪い例:
  detail += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  detail += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  detail += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
//改善例:
  detail += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
           + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
           + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
sample.cs
//効率悪い例:
  detail += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  detail += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
  detail += "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
//改善例:
      StringBuilder retSb = new StringBuilder();
      retSb.Append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
      retSb.Append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
      retSb.Append("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
//※大量の文字列に対し、正規表現を使わないように。非常に遅くなる。

JavaはC#と同様。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TypeScript - Learning Road Map

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

testdata into react state

  const [data, setData] = React.useState(
    [...Array(167)].map((_, index) => ({
      x: index,
      y: Math.floor(Math.random() * 100) + 40,
      date: new Date(),
    })),
  )
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

jsPsych 6.3.0からファイルの事前読み込み方法が変わったよ

今からjsPsychを使い始めようという人も、いままで使っていたよという人にも重要な内容です。2021/2/22にバージョン6.3.0が公開されました。

今回公開された新機能は多岐にわたるのですが、そのなかでもファイルの事前読み込み方法が変わった点は注意が必要かと思い、以下にまとめておきます。

そもそもファイルの事前読み込みはどうして必要なの?

画像や動画、音声ファイルを使った実験では、指定したタイミングでそれらを呈示したいというのが人情です。ところが事前読み込みをしていないと、呈示する段になってあわてて読み込むので、刺激の呈示タイミングに重大な影響を及ぼします。なので事前読み込みは必ずしましょうね、という話です。

6.2.0まではどうやってたの?

基本的にjsPsychは自動で事前読み込みをするように設計されていますが、これが適切に機能するには制約があります。例えばcode1は自動で画像ファイルを読み込んでくれますが、code2は自動で読み込みません。

code1 自動で読み込む
var trial = {
  type: 'image-button-response',
  stimulus: 'file.jpg'
}
code2 自動で読み込まない
var trial = {
  type: 'html-button-response',
  stimulus: '<img src="file.jpg">'
}

code2のようなケースでは次のような形で手動で読み込む必要がありました。

jsPsych.init({
  timeline: [trial],
  preload_images: images, // The image data should be preloaded.
});

6.3.0以降で以下のようにやる

自動で読み込むときと読み込まないときがあると上で説明しましたが、それについては変更はありません。正直なところ、どういうときに自動で読み込むのかを完全に把握するのは結構な手間ですよね・・・。なので私は基本的に手動で読み込むようにしています。どんな場合も手動! 手動は自動を包含します。なので、ここでも手動での説明にしぼります。

まず、事前読み込み用のプラグインを使う点に注意してください。つまり、ファイルの冒頭に以下のような一文が必要になります。

<script src="../plugins/jspsych-preload.js"></script>

それから、事前読み込み用の試行を設けます。

    const images = [ // プログラム内で使用するファイル名を列挙した配列を作ります
        // この例ではimgフォルダに画像がまとまっていると想定していますが、まとまっていなくてもOK
        './img/image1.png',
        './img/image2.png',
        './img/image3.png'
    ];

    const sounds = [
        './sound1.wav',
        './sound2.mp3',
        './sound3.wav'
    ];

    const preload = {
        type: 'preload',
        images: images,
        audio: sounds
    }

そうして、initのtimelineにpreloadを含めます。このとき、実際にファイルを呈示する試行(練習や本試行)よりも前で読み込むように注意してください。

jsPsych.init({
    timeline: [preload, practice, experiment, ... ]
})

めんどくさくなってない?

事前読み込みの方法が、いままでよりも複雑になってないか? そんな声が聞こえてきそうです。私もその点は同意します。ただ、こんなふうに変更した意味がもちろんあるわけですね。

具体的には動画を使うような実験で恩恵を受けると思われます。

動画の事前読み込みは、かなりの時間を要することがあります。私が以前に作ったプログラムでも、実験前に1分以上待つことがありました。あれ? フリーズしてる?って思うくらい。

例えば動画ファイルを3つ使う実験だったとして、実験前に3つのファイルすべてを読み込むのが今までのやり方でした。6.3.0以降では、これを次のように書くことができるようになりました。

jsPsych.init({
    timeline: [preload1, trial1, preload2, trial2, preload3, trial3]
})

つまり、呈示するファイルだけを呈示の直前で読み込むことができるんですね。こうすることで読み込み時間(待ち時間)を分散することができるようになったのです! もちろん、いっきにすべてのファイルを読み込んでも問題がないときには、まとめて読み込むことも可能です。

説明は以上です。

ここで説明したことのほかにも、事前読み込みに失敗しても実験を強行できるオプションや、エラーの詳細を画面に表示したりすることができるようになっています。詳しくは、公式の事前読み込みの概要preloadプラグインの説明をご覧ください。

なお、私が作成したpsychophysicsプラグインを使うときにも事前読み込みを忘れずに行ってくださいね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScript記述中に発生したバグの話

はじめに

ポートフォリオ作成時、画像選択した際にプレビュー表示させる機能をJavaScriptで実装。
実装が完了し、アプリで実際に動作確認を行うと、プレビュー表示自体は実装できているが、他の項目編集を行うと、プレビュー表示が消えてしまうバグが発生しました。

行ったこと

プレビュー表示が既にされている場合、再度画像選択するとプレビュー画像を変更し元からあった画像を削除する機能も実装していたので、
この部分に記述ミス(取得ミス)があるのではと推測。(下記コード)

    imageUser = document.getElementById('user_image')
    if(imageUser){
      document.addEventListener('change', (e) => {
      const imageContent = document.querySelector('img')
      if (imageContent){
        imageContent.remove()
      }
      const file = e.target.files[0]
      const blob = window.URL.createObjectURL(file)

      createImageHTML(blob)
    }

3行目の画像を変更する対象として「document」を指定していたので、ページ内全ての項目変更に対応してしまっていた模様。
下記記述に修正することでバグ解消を行う事ができました。

imageUser.addEventListener('change', (e) => {
const imageContent = document.querySelector('img')
if (imageContent){
imageContent.remove()
}

さいごに

このバグ解消に時間をかなり使ってしまいました。
解決してみると、とても初歩的なミスだと気付いたので、まずは初心に帰る事が大事だなと教訓を得ました。
まだまだJavaScriptについても学習していきます!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

2021年に絶対に入れたいVSCodeの拡張機能

?「ねぇねぇ、ぴえんちゃん。」

?「わおくんどうしたの?」

?「開発環境にVSCode使ってるんだけど、拡張機能ってたくさんあるけど」
?「どれかおすすめとかってない?????」

?「わかった!」
?「じゃあ私が『これがおすすめ!』の拡張機能教えてあげる!」

?「ありがとぉぉぉぉぉぉ!!!」
?「いぃぃぃえぇぇぇぇぇぇ!!!」

Bracket Pair Colorizer 2

?「これを使うと、一致するブラケットを色で識別してくれるの」
?「たくさんブラケットがあっても一目でわかるから便利!」

Bracket Pair Colorizer 2

Remote Containers

?「Remote Containersは、Dockerコンテナをフルに開発環境として使えるの!」
?「新しいチームメンバーが入った時にも簡単に立ち上げて実行できるようになるから!」

?「めっちゃいいじゃぁぁぁぁぁぁぁん!!!!」

Remote Containers

Import Cost

?「Import Costは、JavaScriptとかでインポートしたときのパッケージの推定サイズ数を教えてくれるの!」
?「重すぎる時は赤色で警告を出してくれるから必須!」

Import Cost

Live Share

?「Live Shareは、プロジェクトの仲間と共同編集とか共同デバッグができるの!」
?「音声通話だったりチャットとかもできるから、ペアプロとかもできるね」

Live Share

Quokka.js

?「Quokka.jsは、JavaScript/TypeScriptの開発者の生産性を格段にあげてくれる!」
?「ランタイム値が更新されて横に表示してくるの」

Quokka.js

Better Comments

?「Better Commentsは、わかりやすいコメントを書くときには必須!!!」
?「こんな感じで使いわけがあって他の人がみても分かりやすいよね!」

* ハイライトしたテキストの時
! エラーと警告の時
? 質問の時
// 取り消し線
TODO やること

Better Comments

Settings Sync

?「Settings SyncはGitHub Gistを使って、設定とかワークスペースとかをコンピュータ間で同期できるの」
?「チームで設定を共有したい!って時にもいい!」

Settings Sync

Remote — SSH

?「これは、リモートマシンで開発とかリモートマシンのファイルをVSCodeで編集ができたりするの」
?「例えば、ec2の環境で本番環境とOSを同じにして開発できたり、」
?「複数のマシンから同じ開発環境にアクセスできたりね!」
?「もちろんec2じゃなくてもssh接続できれば、他でも大丈夫!」

Remote — SSH

Prettier

?「Prettierは、コードを解析してコードをフォーマットしてくれるの!」
?「だからコードの一貫性が保たれるからコードがとっても綺麗になるよ!」

Prettier


?「ぜぇぇぇぇぇぇぇんぶ、めっっちゃいい!!!!!!!」
?「これ全部使ってみる!!!!」

?「使ったら感想教えてね!!!」

?「はーーーーーーーーい!!」

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React: メモ化の前に考えるふたつの基本的な手法

Dan Abramov氏による記事「Before You memo()」が2月23日付で公開されました。描画を最適化するために、memouseMemoを使うことは有効です。けれど、その前に考えられる基本的な手法をふたつ紹介されています。記事に示されたコード例を、かいつまんでご説明してみます。

重たいコンポーネントが考えなしに放り込まれたアプリケーション

はじめにとりあげられるのが、重たいコンポーネントを考えなしに放り込んだつぎのコード例です。ExpensiveTreeが負荷の高いコンポーネントを意味します。

import { useState } from 'react';

export default function App() {
    let [color, setColor] = useState('red');
    return (
        <div>
            <input value={color} onChange={(e) => setColor(e.target.value)} />
            <p style={{ color }}>Hello, world!</p>
            <ExpensiveTree />
        </div>
    );
}

コード例のコンポーネントExpensiveTreeは、performance.now()で意図的に負荷を高めています。前掲のコンポーネントAppは、状態が変わるたびに、この重たいコンポーネントも再描画しなければならないわけです。

function ExpensiveTree() {
    let now = performance.now();
    while (performance.now() - now < 100) {
        // Artificial delay -- do nothing for 100ms
    }
    return <p>I am a very slow component tree.</p>;
}

Dan Abramov氏は、この作例からはじまるステップごとに、コードをCodeSandboxに公開しています。

状態を下層に移す

そこで、この問題に対処するひとつめの手法です。状態とその操作を子コンポーネント(Form)に切り分けて、下層に移します。すると、親コンポーネントからは状態がなくなり、子コンポーネントだけが再描画すれば済むのです。

export default function App() {
    // let [color, setColor] = useState('red');
    return (
        <div>
            {/* <input value={color} onChange={(e) => setColor(e.target.value)} />
            <p style={{ color }}>Hello, world!</p> */}
            <Form />

        </div>
    );
}

function Form() {
    let [color, setColor] = useState('red');
    return (
        <>
            <input value={color} onChange={(e) => setColor(e.target.value)} />
            <p style={{ color }}>Hello, world!</p>
        </>
    );
}

こちらがCodeSandboxの作例です。

親に状態をもたせたいとき

問題は、親に状態をもたせたいときです。このような例として、つぎのコードが示されています(作例)。

export default function App() {
    let [color, setColor] = useState('red');
    return (
        // <div>
        <div style={{ color }}>
            <input value={color} onChange={(e) => setColor(e.target.value)} />
            {/* <p style={{ color }}>Hello, world!</p> */}
            <p>Hello, world!</p>
            <ExpensiveTree />
        </div>
    );
}

この場合に使えるふたつめの手法です。やはり、状態は親から子コンポーネント(ColorPicker)に切り出します。そして、負荷の高いコンポーネントや要素もその中に包んでしまうのです。

export default function App() {
    // let [color, setColor] = useState('red');
    return (
        // <div style={{ color }}>
        <ColorPicker>
            {/* <input value={color} onChange={(e) => setColor(e.target.value)} /> */}
            <p>Hello, world!</p>
            <ExpensiveTree />
        {/* </div> */}
        </ColorPicker>
    );
}

子コンポーネント(ColorPicker)の状態とその操作は、前の例と変わりません。注目いただきたいのは、コンポーネントが親からchildrenプロパティを受け取ることです。そして、このプロパティは、状態をもたない親が変更することはありません。その場合、子コンポーネントの中でもchildrenの再描画は行われないのです。

function ColorPicker({ children }) {
    let [color, setColor] = useState('red');
    return (
        <div style={{ color }}>
            <input value={color} onChange={(e) => setColor(e.target.value)} />
            {children}
        </div>
    );
}

これで、重たいコンポーネントの再描画は避けることができました。こちらが、CodeSandboxの作例です。変化するものとしないものを分けるという基本的な考え方が、このふたつの手法に通じているといえるでしょう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Puppeteerでドラッグ&ドロップ

はじめに

最近、フロントテストにPuppeteerというライブラリを用いているのですが、ドラッグ・ドロップの動作においてかなり苦戦をしたので、これ以上犠牲者を増やさないために()、ここに解決策を共有したいと思います。

Puppeteerでドラッグ&ドロップができない!

「Puppeteer drag drop」というように検索をかけると、大体下記のようなコードが出てきます。

    await page.mouse.move(x1, y1);
    await page.mouse.down();
    await page.mouse.move(x2, y2);
    await page.mouse.up();

座標(x1, y1)にカーソルを合わせ、掴む→(x2, y2)に移動し離すという意味のコードです。

しかしこれ...

動作しません!!!!!

正確に言うと、一瞬だけ対象物が動くんですけど、(x2, y2)まで移動してくれないんですよね...
調べてみると、このことに関して困っている方が、国内外問わず結構いました。

await page.mouse.up();
この処理がうまく動作していないのが原因だと思っているが、どうなんだろう。
処理自体にエラーはなく、nodeも正常に終了しています。
しかし私の環境ではテスト終了後、エディタにカーソルをもっていくと常に何かをドラッグしている挙動が発生します。

(Puppeteerで困っていることより引用)

解決策

解決策は、「mouse.moveにoptionsとしてstepsを適切に設定してあげる」です。
公式ドキュメントには

steps <number> defaults to 1. Sends intermediate mousemove events.

と書かれています。
今回はこのstepsを20と設定します。
すなわち、先ほどのコードを

    await page.mouse.move(x1, y1);
    await page.mouse.down();
    await page.mouse.move(x2, y2,{steps: 20});//ここにoptionsとして{steps: 20}を追加した。
    await page.mouse.up();

のように書き換えると、期待通り動作します。

参考

・上記に引用として示したもの
How to simulate Drag-Drop action in pupeteer

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む