■JavaScript
モダン JavaScript チートシート | Modern JS Cheatsheet
https://mbeaudru.github.io/modern-js-cheatsheet/translations/ja-JP.html
【JavaScript】分からない部分まとめてみたら最強だった件 - Qiita
https://qiita.com/TeppeiMimachi/items/b3528b4f37b06383b3cc
2021年に知っておきたいJavaScript最適化技術34選 - Qiita
https://qiita.com/baby-degu/items/396edbaefea64140a5d0
JavaScript で parseInt / parseFloat を使わない方が良い理由
http://nmi.jp/2022-02-03-dont-use-parseInt
JavaScriptのデザインパターンについて
https://zenn.dev/oreo2990/articles/bab298c1d53a81
便利なJavaScriptワンライナー - Qiita
https://qiita.com/tetsuyaohira/items/ac8e1fd3c249eb889753
JavaScriptをもうちょっと理解する54のトピック - Qiita
https://qiita.com/komlabo/items/3f14c8990a2f94fb5323
■基本文法
■変数
スコープ(有効な範囲)は関数内となる
var test1 = "テスト1";
document.write(test1);
■ブロックスコープを持つ変数
スコープはブロックの内部に限定される
変数の有効範囲を限定できるので、varを使うよりも安全なプログラムになる
let test2 = "テスト2";
document.write(test2);
■定数
定数は内容を変更できない
const TEST3 = "テスト3";
document.write(TEST3);
■関数1
function hello1(name) {
document.write("こんにちは" + name + "さん");
}
hello1("テスト4");
■関数2
書き方が変わっても意味はまった同じ
let hello2 = function(name) {
document.write("こんにちは" + name + "さん");
}
hello2("テスト5");
■アロー関数
以下のように関数を定義することもできる
let hello3 = (getname) => {
document.write("こんにちは" + getname + "さん");
}
hello3("テスト6");
関数を引数で渡すときに使うと、コード量を減らせる
function hello4(getname) {
document.write("こんにちは" + getname() + "さん");
}
//hello4(function() { return "テスト7"; });
//hello4(() => { return "テスト7"; });
hello4(() => "テスト7" );
■配列
配列を使えば、複数の値をまとめて管理できる
let myArray = new Array(2, 4, 6, 8);
console.log(myArray);
以下のように「配列リテラル」と呼ばれる記号を使ってスッキリとした記述にもできる
let myArray = [2, 4, 6, 8];
console.log(myArray);
■オブジェクトのプロパティ(値)
let object1 = {
red: 255,
green: 125,
blue: 0
};
document.write(object1.red + ", " + object1.green + ", " + object1.blue);
// 以下のように書くこともできる
document.write(object1['red'] + ", " + object1['green'] + ", " + object1['blue']);
■オブジェクトのメソッド(関数)
let object2 = {
red: 125,
green: 255,
blue: 0,
//code: function() {
code() {
return this.red + ", " + this.green + ", " + this.blue;
}
};
document.write(object2.code());
■コンストラクタ関数
function Object3(r, g, b) {
this.red = r;
this.green = g;
this.blue = b;
this.code = function() {
return this.red + ", " + this.green + ", " + this.blue;
}
};
let object3 = new Object3(125, 0, 255);
document.write(object3.code());
■クラス
ES2015で追加された校分
クラスベース言語の「クラス」を作成するものではなく、「プロトタイプ」の記述を分かりやすくするために実装された
constructor、getter、setter にも対応している
class Object4 {
constructor(r, g, b) {
this.red = r;
this.green = g;
this.blue = b;
}
/*
setCodeRed(r) {
this.red = r;
}
getCodeRed() {
return this.red;
}
*/
set red(r) {
this._red = r;
}
get red() {
return this._red;
}
code() {
return this.red + ", " + this.green + ", " + this.blue;
}
};
let object4 = new Object4(0, 125, 255);
/*
object4.setCodeRed(100);
document.write(object4.getCodeRed());
*/
object4.red = 100;
document.write(object4.code());
■クラスとプロトタイプ
C++やJavaなどでは、クラスと呼ばれる「オブジェクトの設計図」を定義し、その設計図をもとに実態のあるオブジェクトを生成する
実態のあるオブジェクトとして生成されたものをインスタンスと呼ぶ
同じクラスから生成されたインスタンス(実態)は、すべて同じようにメソッド(動作)やプロパティ(値)を持っている
JavaScriptでは「クラスとインスタンス」というように状態を区別することはせず、
「そのオブジェクトがどのようなプロトタイプを持っているか」のように考える
例えば、JavaScriptの配列はすべてArrayオブジェクトのプロトタイプを備えている。言い換えると、最初からインスタンス(実態)となっている
設計図の役割をする「クラス」があるのではなく、オブジェクトそのものが設計図の役割も同時に果たす
先に記載した「Object4」をプロトタイプベースで記述すると、以下のようになる
let Object4 = function() {};
Object4.red = 100;
Object4.green = 125;
Object4.blue = 255;
Object4.prototype.code = function() {
return Object4.red + ", " + Object4.green + ", " + Object4.blue;
};
let object4 = new Object4(0, 125, 255);
document.write(object4.code());
■クラスの継承とオーバーライド
class Object5 extends Object4 {
code() {
return "[" + this.red + ", " + this.green + ", " + this.blue + "]";
}
};
let object5 = new Object5(0, 0, 0);
object5.red = 200;
document.write(object5.red);
document.write(object5.code());
■スクリプトファイルの読み込み
動的に外部ファイルを読み込める
http(s)経由でなければエラーになるので注意
Object6.js
//export default function() {
export default {
return {
red: 200,
green: 200,
blue: 200,
code() {
return this.red + ", " + this.green + ", " + this.blue;
}
};
}
<script type="module">
import Object6 from './Object6.js';
let object6 = new Object6();
document.getElementById('object6').textContent = object6.code();
</script>
<span id="object6"></span>
■正規表現を扱う
■正規表現
if (href.match(/refirio\.net/i)) {
〜処理〜
}
■正規表現で変数を利用
var string = 'refirio.net';
if (href.match(new RegExp(string, 'i'))) {
〜処理〜
}
■正規表現で後方参照
var matches = href.match(/\?shop_id=(.*?)$/);
var data = matches[1];
■正規表現で置換
var text = text.replace(/<br>/g, '');
var text = text.replace(/\n/g, '<br>');
■一定時間後に処理する
以下のように指定すると、一定時間後に処理が実行される
時間はミリ秒で指定するので、500だと0.5秒後となる
setTimeout(function() {
〜処理〜
}, 500);
■定期的に処理する
以下のように指定すると、一定時間ごとに処理が実行される
時間はミリ秒で指定するので、500だと0.5秒ごととなる
timer は、後述する clearInterval で使用できる
var timer = setInterval(function() {
〜処理〜
}, 500);
また、setTimeout によって定期的な処理を終了させることができる
clearInterval(timer);
ゲームやアニメーションでの描画を目的とする場合、requestAnimationFrame の利用を検討するといい
requestAnimationFrameの仕組みと使い方!うまく使ってパフォーマンスを改善しよう! | Tech Blog
https://blog.leap-in.com/use-requestanimtionframe/
setTimeout は requestAnimationFrame に変えるべき? - シンプルシンプルデザイン JavaScript
https://simplesimples.com/web/markup/javascript/settimeout-%E3%81%AF-requestanimationframe-%E3%81%AB...
[JS] アニメーションを行うのに、setTimeoutよりもrequestAnimationFrameを使ってみよう - YoheiM .NET
https://www.yoheim.net/blog.php?q=20130608
■サウンドを再生
【JavaScript】Safari だけじゃないオーディオ再生の制約と再生開始遅延の解決方法 - webfrontend.ninja
https://webfrontend.ninja/js-audio-autoplay-policy-and-delay/
以下のようにすると、サウンドを再生できる
<script>
$(document).ready(function() {
$('#play_sample').on('click', function() {
var audio = new Audio('sound/sample.mp3');
audio.play();
return false;
});
});
</script>
<p><a href="#" id="play_sample">再生</a></p>
以下でも一応再生できるが、iOSだと一度しか再生できない
<script>
$(document).ready(function() {
$('#play_sample').on('click', function() {
$('#audio_sample').get(0).play();
return false;
});
});
</script>
<audio src="sound/sample.mp3" id="audio_sample">
<p>ご利用の環境では再生できません。</p>
</audio>
<p><a href="#" id="play_sample">再生</a></p>
■ムービーを再生
video要素、audio要素をJavaScriptから操作する−HTML5のAPI、および、関連仕様
http://www.htmq.com/video/
<script>
$(document).ready(function() {
$('#play_sample').on('click', function() {
$('#movie_sample').get(0).play();
return false;
});
});
</script>
<video src="movie/sample.mp4" id="movie_sample" width="400" controls>
<p>ご利用の環境では再生できません。</p>
</video>
<p><a href="#" id="play_sample">再生</a></p>
■ブラウザバックでの遷移を判定
ブラウザ依存があるようだが、以下2つの両方を使えば判定できそうな
いざ使うとなれば各実機での検証は必要
ブラウザバックで画面遷移してきたことを判定し、処理を動かす - Qiita
https://qiita.com/sakusaku_tempura/items/5b6d7d3a77d7b0cb3e3a
$(document).ready(function() {
if (window.performance.navigation.type == 2) {
console.log('ブラウザの履歴をたどって移動しました。(window.performance)');
}
});
[javascript]ブラウザの戻るボタンで戻ってきた時になんらかの処理をする方法
https://www.yukiiworks.com/archives/236
window.onpageshow = function(event) {
if (event.persisted) {
console.log('ブラウザの履歴をたどって移動しました。(event.persisted)');
}
};
■jQueryなしでHTMLを操作する
【脱jQuery】jQuery <=> vanillaJS 書き換え集
https://zenn.dev/kobito/articles/5e246e85615435
【JavaScript入門】querySelector()によるHTML要素の取得方法まとめ! | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト
https://www.sejuku.net/blog/70581
もうjQueryには頼らない!素のJavaScriptでDOMを操作するための基礎知識 - WPJ
https://www.webprofessional.jp/dom-manipulation-vanilla-javascript-no-jquery/
jQueryからネイティブJavaScriptへ置き換えの第一歩 - Qiita
https://qiita.com/nayuneko/items/b3ad3d6bc2687bcdb0f6
非jQuery環境ではどう書んだっけ?チートシート - Qiita
https://qiita.com/tatesuke/items/261ad51426d11b4efe26
jQueryは使わない!ネイティブJavaScriptで実装してみた10選 ← kannart WEB HACKS
https://blog.kannart.co.jp/coding/1199/
【脱jQuery!】ネイティブなJavaScript(Vanilla JS)への書き換え方まとめ | WEMO
https://wemo.tech/2101
■Promise
とほほのPromise入門 - とほほのWWW入門
http://www.tohoho-web.com/ex/promise.html
4歳娘「パパ、Promiseやasync/awaitって何?」〜Promise編〜 - Qiita
https://qiita.com/Yametaro/items/0d29df53d9ac2a779595
【JavaScript】本日未明、[ async - await ]さんが死体で発見され... - Qiita
https://qiita.com/impl_s/items/8ffbe865b8c53a75cfe3
■ライブラリを作成する
オリジナルのJavaScriptライブラリを公開しよう
https://zenn.dev/yusuke99/books/fcd96342f5cb1b468799
■数学
■正弦定理と余弦定理
sin(正弦) ... 正角に対する弦の長さ
sin(サイン)は英語のsinusoid(正弦曲線)から来ている
cos(余弦) ... 余角に対する弦の長さ
cos(コサイン)は「co-sine」で、「sin」に、補足的・補完的(complementary)の意味を有する接頭辞「co」を付したもの
三角比の正弦余弦正接ってどういう意味?【sin・cos・tanに結びつく覚え方のコツ】 | 遊ぶ数学
https://integraldx.info/sine-cosine-tangent-143
数学記号の由来について(7)−三角関数(sin、cos、tan等)− |ニッセイ基礎研究所
https://www.nli-research.co.jp/report/detail/id=65715?site=nli
正弦定理 ... 三角形の正弦(sinθ)の比は3辺の長さの比に等しいというもの
つまり、△ABCにおいて、「sinA:sinB:sinC = a:b:c」が成り立つ
余弦定理 ... 三角形の2辺と1角が分かっている場合、残りの辺の長さを求めることができる公式
また、3辺が分かっている場合、余弦(cos)を求めることも
正弦定理と余弦定理の公式・証明・例題を数学講師がわかりやすく解説 | お知らせ | 好文館|福岡と熊本の個別指導塾(英語・数学)
https://www.koubunkan-n.jp/news/seigen-yogen/
■角度と三角比
日常的に角度を表現する場合、「〇度」というように度数を使って表現する
これは「度数法」と呼ばれるもので、角度の状態をイメージしやすく、直観的で分かりやすい
プログラミングの際には、角度を度数法ではなく「弧度法」を用いることが多い
コンピュータで計算を行う上では、計算量を節約できるなどのメリットがある
弧度法では「ラジアン」と呼ばれる尺度で角度を表現する
ラジアンは「円周の長さを基準とした角度の表現」で、「半径が1の円の外周の、その長さを用いて表現されるもの」と言える
度数法の180度は、弧度法では円周率(約3.14)となる
度数法の360度は、弧度法では円周率の2倍(約6.28)となる
つまり、「1ラジアン = 円の半径 = r」となる(円周は「2πr」で表される)
// 角度(30度)
let degrees = 30;
// 角度からラジアンを取得
let radian = degToRad(degrees);
// 結果を出力
console.log(radian); // 0.5235987755982988
// 度数からラジアンへの変換
function degToRad(degrees) {
return degrees * Math.PI / 180;
//return (degrees / 360) * (Math.PI * 2); // 整理前
}
sinとcosを使用すると、
「半径1の円を基準とした、角度に応じた座標」を求めることができる
具体的には、その座標は (x, y) = (cosθ, sinθ)となる
// 角度(30度)
let degrees = 30;
// 角度からラジアンを取得
let radian = degToRad(degrees);
// サインとコサインを求める
let sin = Math.sin(radian);
let cos = Math.cos(radian);
// 結果を出力
console.log(sin); // 0.49999999999999994
console.log(cos); // 0.8660254037844387
// 度数からラジアンへの変換
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
これを利用することで、「任意の角度の方向への移動後の座標」を求めることができる
// 任意の座標A(ここでは仮に原点とする)
let A = [0.0, 0.0];
// 任意の角度(ここでは仮に30度とする)
let degrees = 30;
// 任意の移動量(ここでは仮に1とする)
let speed = 1;
// 角度からラジアンを取得
let radian = degToRad(degrees);
// サインとコサインを求める
let sin = Math.sin(radian);
let cos = Math.cos(radian);
// 移動量
let B = [
A[0] + cos * speed,
A[1] + sin * speed
];
// 結果を出力
console.log(A); // [0, 0]
console.log(B); // [0.8660254037844387, 0.49999999999999994]
// 度数からラジアンへの変換
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
■ベクトル
量を表すことができる概念を「スカラー」や「実数」と呼ぶ
量という概念の他に「向き」の概念が新たに加わったものを「ベクトル」と呼ぶ
例えば2次元の平面にAとBという2つの点がある場合、AとBの距離は単体の値(スカラー)で表すことができる
このとき、AからBに向かう方角(向き)を表現しようとすると単体の数値で表すことはできず、
横方向と縦方向の移動量を組み合わせて (x, y)のように複数の値をひとまとめにして表現する。これがベクトル
ベクトルは「終点 - 始点」という計算を行うことによって求めることができる
// 視点
let A = [-2, 2];
// 終点
let B = [3, -1];
// 任意の角度(ここでは仮に30度とする)
let degrees = 30;
// 2点間を結ぶベクトル
let V = [
B[0] - A[0], // X軸の終点から始点を引く
B[1] - A[1] // Y軸の終点から始点を引く
];
// 結果を出力
console.log(V); // [5, -3]
■単位ベクトル
ベクトルの大きさを「1」に揃えることで、純粋にベクトルの向きだけを考えられるようになる
この作業を「単位化」といい、大きさが1になったベクトルのことを「単位ベクトル」と呼ぶ
単位化されたベクトルの各要素は、その値が -1〜1 の範囲に必ず収まる
また単位ベクトルは、その先端(終点)が必ず「半径1の円」の外周に重なる
// ベクトル
let V = [5, -3];
// ベクトルの大きさを求める
let L = Math.sqrt(V[0] * V[0] + V[1] * V[1]);
// ベクトルの単位化
V[0] /= L;
V[1] /= L;
// 結果を出力
console.log(L); // 5.830951894845301
console.log(V); // [0.8574929257125441, -0.5144957554275265]
この「半径1の円」は角度と三角比でも登場したが、
同じ角度を元にしたサインやコサインで得られる値をベクトルとして表現すると、それは常に単位ベクトルとなる
三角関数には、サインの値からラジアンを求めるアークサイン(arcsin / 逆正弦)や、コサインの値からラジアンを求めるアークコサイン(arccos / 逆余弦)がある
任意のベクトルVが定義できるとき、それを単位化してから要素をアークサインやアークコサインに与えると、ベクトルが成す角度が得られる
// サインとコサインの値
let sin = 0.49999999999999994;
let cos = 0.8660254037844387;
// アークサインとアークコサインでラジアンを求める
let radianA = Math.asin(sin);
let radianB = Math.acos(cos);
// ラジアンから角度を取得
let A = radToDeg(radianA);
let B = radToDeg(radianB);
// 結果を出力
console.log(radianA); // 0.5235987755982988
console.log(radianB); // 0.5235987755982987
console.log(A); // 29.999999999999996
console.log(B); // 29.999999999999993
// ラジアンから度数への変換
function radToDeg(radian) {
return 180 / Math.PI * radian;
}
■ベクトルの加算と減算
ベクトルは、スカラーと同じように加算と減算が行える
ベクトル同士の加算や減算は、単にベクトルを構成するXやYなどの要素ごとに、それぞれ加算と減算を行う
// ベクトル
let V = [5, -3];
let W = [-2, 6];
// ベクトルの加算(V + W)
let A = [
V[0] + W[0],
V[1] + W[1]
];
// 結果を出力
console.log(A); // [3, 3]
// ベクトルの加算(V - W)
let B = [
V[0] - W[0],
V[1] - W[1]
];
// 結果を出力
console.log(B); // [7, -9]
■ベクトルのスカラー倍
ベクトルには、掛け算や割り算の計算方法は無い
しかし「スカラー倍」と呼ばれる、ベクトルをスケール(拡大縮小)する方法がある
これは単に、ベクトルを構成する各要素に対して、何らかの値(スカラー)を掛けることで実現する
// ベクトル
let V = [5, -3];
// スケールするためのスカラーの定義
let scalar = 2.0
// ベクトルVをスカラー倍する
let W = [
V[0] * scalar,
V[1] * scalar
];
// 結果を出力
console.log(W); // [10, -6]
■ベクトルの内積と外積
ベクトルの内積とは、「ベクトル同士の成す角」のこと
結果は必ずスカラーになる
また、単位化したベクトル同士の内積はcosθに等しくなる
// 2つのベクトルを定義
let V = [5, 1];
let W = [-2, 3];
// それぞれベクトルを単位化する
V = normalize(V);
W = normalize(W);
// 単位化したベクトル同士で内積を求める
let dotValue = dot(V, W);
// 内積の結果はcosθなので、アークサインでラジアンを得られる
let rad = Math.acos(dotValue);
// ラジアンから度数への変換
let deg = radToDeg(rad);
// 結果を出力
console.log(rad); // 1.9614033704925835
console.log(deg); // 112.38013505195958
// ベクトルを単位化
function normalize(v) {
let len = Math.sqrt(v[0] * v[0] + v[1] * v[1]);
return [v[0] / len, v[1] / len];
}
// ベクトルの内積を求める
function dot(v0, v1) {
return (v0[0] * v1[0]) + (v0[1] * v1[1]);
}
// ラジアンから度数への変換
function radToDeg(radian) {
return 180 / Math.PI * radian;
}
以下、勉強中
必要になった時に改めて勉強することにしたい
単位化したベクトル同士の外積はsinθに等しくなる
内積は高校数学範囲だが、外積は高校数学範囲外らしい
コサイン(内積)は「左右の方向、もしくは垂直」を判定するのに使うことができる
サイン(外積)は「上下の方向、もしくは水平」を判定するのに使うことができる
サイン単体あるいはコサイン単体では、それぞれ「縦横どちらかの向き」しか判定できない
まとめると、以下のようになる
・単位ベクトル同士の内積は、コサインに相当する
・単位ベクトル同士の外積は、サインに相当する
・内積の結果が0のとき、ベクトル同士は垂直である
・外積の結果が正の値であるとき、両社の成す角は鋭角である
・外積の結果が負の値であるとき、両社の成す角は鈍角である
・外積の結果が0のとき、ベクトル同士は並行である
・外積の結果が正の値であるとき、ベクトルAから見て上(左側)にベクトルBがある
・外積の結果が負の値であるとき、ベクトルAから見て下(右側)にベクトルBがある
■行列
行列は、ベクトルを変形したり変換したりする際に、よく用いられる
回転行列を用いたベクトルの回転など、
必要になった時に改めて勉強することにしたい