比較演算子
比較演算子を忘れないようにメモ。
=(イコール)一つだと代入という意味になってしまうので、等しいはイコール2つ。
== | 等しい |
!= | 等しくない |
< | 小さい |
<= | 以下 |
> | 大きい |
>= | 以上 |
=== | 型も等しい |
!== | 型も等しくない |
文字列か数値か
Javascriptで
5 + 5 = 10だけど、
5 + ‘5’ = 55になる。
つまり、文字列なのか数値なのかは、型をはっきりさせておかないといけない。
よく分かる例がprompt関数。
const n = prompt(‘数字を入力してください’);
console.log(n + 5);
prompt関数で入力したものは文字列とみなされます。
だから例えば15と入力すれば、
15 + 5 で 20と表示されると思いきや、文字列の連結と認識されるので、
155と出力されます。
この入力文字を数字として認識させるには、
console.log( Number(n) + 5 ); とすればOK!
そうすれば20と表示されます。
初めから
const n = Number(prompt(‘数字を入力してください’));
とも入力可能です。
+=
sum += element;
は、以下を表します。
sum = sum + element;
+=を使うときの注意点
+= は数値と文字列の両方を使用することができます。
よって、数値なのか文字列なのかをはっきりさせないと、予期しない動作になってしまいます。
数値の場合
let sum = 0;
sum += 5;
console.log(sum); // 5
文字列の場合
let concatenatedString = "";
concatenatedString += "Hello, ";
concatenatedString += "world!";
console.log(concatenatedString); // "Hello, world!"
もう一つ注意する点は、初期化をするということ。
let sum = 0;のように初期化していないと、NaN(Not-a-Number)になってしまいます。
let sum;
sum += 5; // sumは未定義(undefined)のまま5が加算されようとするため、NaN(Not-a-Number)になる
console.log(sum); // NaN
null
nullとは、「値を持たない」「有効な値が存在しない」こと。
0や’’(空文字)はnullではないので要注意。
null == 0 も null === 0 もfalse
null == ”” も null === ”” もfalse
if文
言語によってif elseなのかelse ifなのかこんがらがるので、メモメモ。
if(){
} else if {
} else {
}
が正しい。最後にセミコロンは不要。
早期リターン
特殊なケースを先に振るい落とすための早期リターンがあります。
function checkString(str) {
// 特殊なケース: 文字列が空の場合
if (str === '') {
return 'エラー: 文字列が空です';
}
// 通常の処理
return '文字列の長さは ' + str.length + ' です';
}
console.log(checkString('Hello')); // 出力: 文字列の長さは 5 です
console.log(checkString('')); // 出力: エラー: 文字列が空です
console.log(checkString('Test')); // 出力: 文字列の長さは 4 です
switch文
分岐する値が明確な時はif文ではなく、switch文を使うとよいです。
switch(color) {
case 'red':
console.log('赤');
break;
case 'blue':
console.log('青');
break;
case 'yellow':
case 'orange'
console.log('黄色系');
break;
default:
console.log('なし');
break;
}
if文同様最後にセミコロンは不要。
条件を2つにする場合は、caseを2行にすればOKです。
for文
次は反復処理のfor文について。
for文もカンマで区切るかセミコロンで区切るのかを混同しやすいので、メモメモ。
consoleではテンプレートリテラルも使用しています。
for ( let i = 0; i < 10; i++) {
console.log("繰り返すのは" + i +"回");
console.log(`${i} 回繰り返す`);
}
while文
繰り返す回数が決まっている場合はfor文でいいですが、決まっていない場合はwhile文を使うことができます。
while(条件式){
}
do while文
では、do while文はwhile文とどのような違いがあるでしょうか?
while文は先に条件判定をしたいとき
do while文は1回は実行して、そのあとで条件判定するとき
になります。
do {
} while (条件式);
do whileは最後にセミコロンが必要です。
forEach文
array.forEach(function(element, index, array) {})
引数は3つ。
- 現在の配列要素
- 現在の配列要素のインデックス
- forEachが呼び出された元の配列
です。
私はforEach文で何度もnot a functionとエラーになったことがあります。
その原因のほとんどはarrayが配列オブジェクトではないということでした。
悪い例
const obj = { a: 1, b: 2, c: 3 };
obj.forEach(element => console.log(element)); // エラー: obj.forEach is not a function
良い例
const array = [1, 2, 3];
array.forEach(element => console.log(element)); // 正常に動作する例
対策
Array.isArray()を使って配列かどうかの確認
if (Array.isArray(array)) {
array.forEach(element => console.log(element));
} else {
console.log("This is not an array");
}
Array.from()で配列に変換
const nodeList = document.querySelectorAll('div');
Array.from(nodeList).forEach(element => console.log(element));
また、arrayがnullやundefinedの場合エラーになるので、デフォルト値を設定するとよいでしょう。
const array = maybeUndefinedOrNullArray || [];
array.forEach(element => console.log(element));
三項演算子
score > 70 ? 'A' : 'B'
score > 70が成立していたらA、成立していなかったらBという意味になります。
三項演算子は変数に代入して使うことが可能。
関数宣言と関数式
関数宣言
実行タイミングは関数定義前・関数定義後、同じ関数名・変数名を使うと上書きされる。
function double(num) {
return num * 5;
}
関数式
実行タイミングは関数定義後のみ、同じ関数名・変数名を使うとエラーになる。つまり、同じ関数を定義するのを未然に防げる
const double = function(num) {
return num *5;
};
関数式にはセミコロンが必要です。
アロー関数式
アロー関数はES6から導入された書き方。
const double = (num) => {
return num * 5;
};
引数が1つの場合は以下のように書くことができます。
const double = num => {
return num * 5;
};
さらに戻り値が1文の場合は以下のようになります。
const double = num => num * 5;
オブジェクトが複数ある場合にはかっこ()を使えば1文として扱えます。
const func = (num1, num2) =>({
number01 : num1,
number02 : num2
})
console.log(func(10, 20))//{number01: 10, number02 : 20}
アロー関数の注意点~thisについて
アロー関数の注意点は、thisの値が変わることです。
通常の関数・・・呼び出し方によって this が変わる
アロー関数・・・thisは定義された時の外側のthisを固定する(=レキシカルスコープ)
function Person(name) {
this.name = name;
setTimeout(function() {
console.log('通常関数:', this.name); ← グローバルに name がなければ undefined
}, 100);//この関数は、setTimeout が呼び出しているので、this はデフォルトで グローバルオブジェクト(ブラウザなら window、Node.js なら global)になります。
setTimeout(() => {
console.log('アロー関数:', this.name); // Person インスタンスの this
}, 100);//外側(ここでは Person 関数内)の thisをそのまま使います。
}
new Person("Taro");
通常の関数でthisを保持する方法を2つ
function Person(name) {
this.name = name;
const self = this; // ← 外の this を保存
setTimeout(function() {
console.log("self を使う:", self.name); // ✅ 太郎
}, 100);
}
const p = new Person("太郎");
function Person(name) {
this.name = name;
setTimeout(function() {
console.log("bind を使う:", this.name); // ✅ 太郎
}.bind(this), 100); // ← ここで this を固定
}
const p = new Person("太郎");
インスタンスを作るコンストラクタ関数では、アロー関数は避けたほうがよさそうです。
なぜなら
アロー関数は自分自身のthisを持たない、
そして
コンストラクタはnewで呼ばれることを想定しているから。
即時関数
(function(仮引数){}) (実引数);
(function() {
// 初期化処理
const apiUrl = "https://api.example.com";
const apiKey = "12345";
// API初期設定
console.log(`APIが設定されました: ${apiUrl}`);
})();
即時関数はブロックスコープやモジュール機能がなかったES5以前にカプセル化やスコープ・クロージャとして使われました。
即時関数とは定義と同時に実行される関数です。
(function() {
// 関数内部で定義された変数や関数は外部からアクセスできない
var hidden = "この変数は外部から見えない";
console.log("Hello, world!");
})();
カプセル化
カプセル化とは、データや処理をオブジェクトや関数内に隠蔽して、外部から直接アクセスできないようにすることです。
即時関数を使うことで、外部から直接アクセスしたくない変数や処理をカプセル化できます。
(function() {
var hidden = "これは外部から見えない";
window.exposed = "これは外部から見える"; // 外部に公開
})();
// console.log(hidden); // Error: hidden is not defined
console.log(exposed); // "これは外部から見える"
ここでは、hidden
という変数は即時関数のスコープ内で隠蔽されているので、外部からアクセスできません。一方、exposed
はwindow
オブジェクトに公開されているので、外部からアクセスできます。このように、即時関数を使うことで、必要なデータや処理をカプセル化できます。
スコープ
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}結果:5が5回出力される
通常のfor
ループでは、setTimeout
の中で参照されるi
が最後に更新された値(5)を持ってしまいますが、即時関数を使うことで、各反復ごとのi
が個別のスコープに閉じ込められ、期待通りの動作になります。
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i);
}結果:0 1 2 3 4
クロージャ
クロージャは、関数が定義されたスコープの外でも、そのスコープにある変数にアクセスできる仕組みです。即時関数を使うと、クロージャを作り、関数が外部の変数にアクセスすることを制限したり、管理したりできます。
例えば、次のように、関数内でクロージャを作り、外部からアクセスできないように変数を保持することができます。
var counter = (function() {
var count = 0; // 外部からアクセスできない
return {
increment: function() {
count++;
console.log(count);
},
decrement: function() {
count--;
console.log(count);
}
};
})();
counter.increment(); // 1
counter.increment(); // 2
counter.decrement(); // 1
// console.log(count); // Error: count is not defined
この場合、count
変数は即時関数内でカプセル化されており、increment
やdecrement
関数を通じてのみアクセスできます。外部から直接count
にはアクセスできないため、状態管理がしやすくなります。
非同期処理
async/await
async
は関数の前につけて、その関数を常に Promise
を返すようにします。await
は Promise
が解決するまで待機するキーワードです。
async function fetchData() {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
console.log(data);
}
fetchData();
Promise
Promise
は非同期処理の結果を表すオブジェクトで、まだ完了していない非同期処理が成功または失敗した結果を取り扱います。
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("非同期処理成功");
}, 1000);
});
promise.then((result) => {
console.log(result); // "非同期処理成功"
}).catch((error) => {
console.log(error); // エラーがあれば
});
fetch()
fetch()
は非同期処理であり、Promise
を返します。これにより、リクエストが完了するのを待って結果を処理することができます。
fetch(url, options)
.then(response => response.json()) // レスポンスをJSONとしてパース
.then(data => console.log(data)) // JSONデータを利用
.catch(error => console.error('Error:', error)); // エラーハンドリング
options(任意)は、HTTPメソッド(GET、POST、PUTなど)、ヘッダー、ボディの内容などを設定できます。デフォルトはGET。
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST', // HTTPメソッド
headers: {
'Content-Type': 'application/json' // JSON形式のデータを送信
},
body: JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
})
})
.then(response => response.json()) // レスポンスをJSONとしてパース
.then(data => console.log(data)) // サーバーから返されたデータを利用
.catch(error => console.error('Error:', error));