🔢 JavaScript演算子 基礎ガイド

Node-RED / Node.js / JavaScript で使う演算子

このガイドでは、Node-REDのFunctionノードやSwitchノードで使うJavaScript演算子について、初心者の方でも理解できるように詳しく説明します。

📚 1. 演算子とは?

🤔 「演算子」って何?

演算子(オペレータ)とは、計算や比較を行うための記号です。 日常生活で例えると、電卓のボタンのようなものです。 「+」を押せば足し算、「-」を押せば引き算ができるように、プログラムでも記号を使って様々な処理を行います。

🧮 電卓に例えると:

📋 演算子の種類

+ - * / 算術演算子

数値の計算を行う

足し算、引き算、 掛け算、割り算など

== != < > 比較演算子

値を比較してtrue/falseを返す

等しい、大きい、 小さい、以上、以下

&& || ! 論理演算子

複数の条件を組み合わせる

かつ(AND)、 または(OR)、否定(NOT)

= += -= 代入演算子

変数に値を設定する

代入、加算代入、 減算代入など

➕ 2. 算術演算子(四則演算)

数値の計算を行う演算子です。小学校で習った算数と同じ概念ですが、記号が少し異なります。

🔢 算術演算子一覧
演算子 名前 結果 説明
+ 加算(足し算) 10 + 3 13 左右の値を足す
- 減算(引き算) 10 - 3 7 左から右を引く
* 乗算(掛け算) 10 * 3 30 左右の値を掛ける(×ではなく*)
/ 除算(割り算) 10 / 3 3.333... 左を右で割る(÷ではなく/)
% 剰余(余り) 10 % 3 1 割り算の余りを求める
** べき乗 2 ** 3 8 2の3乗 = 2×2×2

📌 よく使う剰余演算子(%)の使い道:

🔧 Node-REDでの使用例(Functionノード)

Inject
(数値)
Function
(計算)
Debug
// Functionノードでの算術演算の例 // センサーデータを受け取って計算 let temperature = msg.payload.temperature; // 25.5 let humidity = msg.payload.humidity; // 60 // 足し算 let sum = temperature + humidity; // 85.5 // 平均値の計算 let average = (temperature + humidity) / 2; // 42.75 // 温度をファーレンハイトに変換 let fahrenheit = temperature * 9 / 5 + 32; // 77.9 // 10件ごとに処理(剰余の活用) let count = msg.payload.count; if (count % 10 === 0) { // 10件目、20件目、30件目...で実行 node.warn("10件処理しました: " + count); } msg.payload = { sum: sum, average: average, fahrenheit: fahrenheit }; return msg;

⚠️ 文字列の「+」に注意!

+ は文字列を連結する機能もあります。数値と文字列を足すと予期しない結果になります。

"10" + 3 → "103" // 文字列連結になってしまう 10 + 3 → 13 // 数値の足し算 Number("10") + 3 → 13 // 数値に変換してから計算

⚖️ 3. 比較演算子

2つの値を比較して、true(真)またはfalse(偽)を返す演算子です。 条件分岐(if文やSwitchノード)で必須の知識です。

🔍 比較演算子一覧
演算子 名前 結果 説明
=== 厳密等価 5 === 5 true 値と型が両方同じ(推奨)
!== 厳密不等価 5 !== "5" true 値または型が異なる(推奨)
== 等価 5 == "5" true 型変換後に値が同じ(非推奨)
!= 不等価 5 != "5" false 型変換後に値が異なる(非推奨)
< 小なり 3 < 5 true 左が右より小さい
> 大なり 3 > 5 false 左が右より大きい
<= 以下 5 <= 5 true 左が右以下
>= 以上 3 >= 5 false 左が右以上

🎯 === と == の違い(重要!)

5 === 5
✓ true
数値と数値、値も型も同じ
5 === "5"
✗ false
数値と文字列、型が違う
5 == "5"
✓ true
型変換後に比較(危険)

💡 === を使うべき理由:

== は型変換を行うため、予期しない結果を招くことがあります。 バグの原因になりやすいため、常に ===(厳密等価)を使うことを推奨します。

// 危険な例(==を使用) 0 == "" // true(両方falsy値として扱われる) 0 == false // true "" == false // true null == undefined // true // 安全な例(===を使用) 0 === "" // false 0 === false // false "" === false // false null === undefined // false

🔧 Node-REDでの使用例(Switchノード)

Inject
(温度)
Switch
(条件分岐)
→→→ Debug
(高温/正常/低温)

Switchノードでは比較演算子を視覚的に設定できます:

// Switchノードの条件設定例 条件1: msg.payload > 30 → 出力1(高温アラート) 条件2: msg.payload >= 20 → 出力2(正常) 条件3: msg.payload < 20 → 出力3(低温アラート)

🔧 Functionノードでの使用例

// Functionノードでの比較演算の例 let temperature = msg.payload; // 単純な比較 if (temperature > 30) { msg.payload = "高温警報"; msg.level = "danger"; } else if (temperature >= 20) { msg.payload = "正常"; msg.level = "normal"; } else { msg.payload = "低温警報"; msg.level = "warning"; } // 厳密等価での比較 if (msg.topic === "sensor_A") { // センサーAからのデータのみ処理 } // 範囲チェック(20以上30以下) if (temperature >= 20 && temperature <= 30) { msg.payload = "適正範囲内"; } return msg;

🔗 4. 論理演算子

複数の条件を組み合わせたり、条件を反転させる演算子です。

🧠 論理演算子一覧
演算子 名前 結果 説明
&& AND(かつ) true && true true 両方trueの場合のみtrue
|| OR(または) true || false true どちらかがtrueならtrue
! NOT(否定) !true false true/falseを反転

論理演算の真理値表

A B A && B A || B !A
true true true true false
true false false true false
false true false true true
false false false false true

📌 日常生活での例え:

🔧 Node-REDでの使用例

// Functionノードでの論理演算の例 let temperature = msg.payload.temperature; // 温度 let humidity = msg.payload.humidity; // 湿度 let isActive = msg.payload.isActive; // センサー稼働中 // AND: 両方の条件を満たす場合 if (temperature > 30 && humidity > 80) { msg.payload = "熱中症警報: 高温多湿"; } // OR: どちらかの条件を満たす場合 if (temperature > 35 || humidity > 90) { msg.payload = "危険警報"; } // NOT: 条件の反転 if (!isActive) { msg.payload = "センサー停止中"; return msg; // 処理を中断 } // 複合条件 // 稼働中 かつ (高温 または 高湿度) if (isActive && (temperature > 30 || humidity > 80)) { msg.alert = true; } return msg;

📝 5. 代入演算子

変数に値を設定したり、計算結果を代入する演算子です。

✏️ 代入演算子一覧
演算子 名前 同等の処理 説明
= 代入 x = 5 - 値を変数に設定
+= 加算代入 x += 3 x = x + 3 足して代入
-= 減算代入 x -= 3 x = x - 3 引いて代入
*= 乗算代入 x *= 3 x = x * 3 掛けて代入
/= 除算代入 x /= 3 x = x / 3 割って代入
++ インクリメント x++ x = x + 1 1を足す
-- デクリメント x-- x = x - 1 1を引く
// 代入演算子の使用例 let count = 0; // 基本の代入 count = 10; // count は 10 // 加算代入(カウンターでよく使用) count += 1; // count は 11 count++; // count は 12(同じ意味) // 減算代入 count -= 5; // count は 7 // 乗算代入 count *= 2; // count は 14 // 文字列の連結にも使える let message = "Hello"; message += " World"; // message は "Hello World"

⚡ 6. 演算子の優先順位

複数の演算子を使う場合、計算される順序があります。数学の四則演算と同じく、掛け算・割り算が先に計算されます。

📊 優先順位(高い順)
優先度 演算子 説明
1(最高) () 括弧(グループ化)
2 ! ++ -- 否定、インクリメント
3 ** べき乗
4 * / % 乗算、除算、剰余
5 + - 加算、減算
6 < <= > >= 比較(大小)
7 === !== == != 等価比較
8 && 論理AND
9 || 論理OR
10(最低) = += -= など 代入

📌 迷ったら括弧を使う!

優先順位を覚えるより、括弧 () を使って明示的に計算順序を指定するのが安全です。

// わかりにくい let result = a + b * c > d && e || f; // わかりやすい(括弧で明示) let result = ((a + (b * c)) > d) && e) || f;

🎯 7. Node-REDでの活用場所

📍 Functionノード

JavaScriptコードを直接書くため、すべての演算子が使用可能です。

Inject Function Debug

📍 Switchノード

比較演算子をGUIで設定できます。

// Switchノードで設定できる条件 == (等しい) != (等しくない) < (より小さい) <= (以下) > (より大きい) >= (以上) is true / is false is null is not null など

📍 Changeノード

JSONata式を使って演算が可能です。

// Changeノードでの JSONata式 例 $sum(payload.values) // 配列の合計 payload.price * payload.quantity // 掛け算 payload.temperature > 30 // 比較(true/false)

📍 Templateノード

Mustache記法では演算子は使えませんが、JavaScript処理を挟めば可能です。

🏋️ 8. 実践演習

演習1: 基本的な計算初級

📝 課題:

2つの数値を受け取り、四則演算の結果をすべて出力してください。

🎯 要求仕様:

✅ 成功の条件:

💡 ヒント

Injectノードの設定:

  • payload: JSON型で {"a": 10, "b": 3}

Functionノードのコード:

  • msg.payload.a と msg.payload.b で値を取得
  • 各演算結果を新しいオブジェクトにまとめる
✅ 解答例フロー
[ { "id": "ex1_inject", "type": "inject", "name": "数値入力", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "{\"a\":10,\"b\":3}", "payloadType": "json", "x": 120, "y": 100, "wires": [["ex1_function"]] }, { "id": "ex1_function", "type": "function", "name": "四則演算", "func": "let a = msg.payload.a;\nlet b = msg.payload.b;\n\nmsg.payload = {\n sum: a + b,\n diff: a - b,\n product: a * b,\n quotient: a / b,\n remainder: a % b\n};\n\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 300, "y": 100, "wires": [["ex1_debug"]] }, { "id": "ex1_debug", "type": "debug", "name": "結果", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 470, "y": 100, "wires": [] } ]

演習2: 温度判定初級

📝 課題:

温度に応じて3段階の判定結果を出力してください。

🎯 要求仕様:

✅ 成功の条件:

💡 ヒント

Switchノードの設定:

  • プロパティ: msg.payload
  • 条件1: > 30
  • 条件2: >= 20(条件1で30超は除外されている)
  • 条件3: その他(otherwise)
✅ 解答例フロー
[ { "id": "ex2_inject_high", "type": "inject", "name": "35度", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "topic": "", "payload": "35", "payloadType": "num", "x": 110, "y": 80, "wires": [["ex2_switch"]] }, { "id": "ex2_inject_normal", "type": "inject", "name": "25度", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "topic": "", "payload": "25", "payloadType": "num", "x": 110, "y": 140, "wires": [["ex2_switch"]] }, { "id": "ex2_inject_low", "type": "inject", "name": "15度", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "topic": "", "payload": "15", "payloadType": "num", "x": 110, "y": 200, "wires": [["ex2_switch"]] }, { "id": "ex2_switch", "type": "switch", "name": "温度判定", "property": "payload", "propertyType": "msg", "rules": [ {"t": "gt", "v": "30", "vt": "num"}, {"t": "gte", "v": "20", "vt": "num"}, {"t": "else"} ], "checkall": "false", "repair": false, "outputs": 3, "x": 280, "y": 140, "wires": [["ex2_debug_high"], ["ex2_debug_normal"], ["ex2_debug_low"]] }, { "id": "ex2_debug_high", "type": "debug", "name": "高温", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "'高温: ' & payload & '度'", "targetType": "jsonata", "statusVal": "payload", "statusType": "auto", "x": 450, "y": 80, "wires": [] }, { "id": "ex2_debug_normal", "type": "debug", "name": "適温", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "'適温: ' & payload & '度'", "targetType": "jsonata", "statusVal": "payload", "statusType": "auto", "x": 450, "y": 140, "wires": [] }, { "id": "ex2_debug_low", "type": "debug", "name": "低温", "active": true, "tosidebar": true, "console": false, "tostatus": true, "complete": "'低温: ' & payload & '度'", "targetType": "jsonata", "statusVal": "payload", "statusType": "auto", "x": 450, "y": 200, "wires": [] } ]

演習3: 複合条件判定中級

📝 課題:

温度と湿度の複合条件でアラートを判定してください。

🎯 要求仕様:

✅ 成功の条件:

💡 ヒント

Functionノードのポイント:

  • && (AND) と || (OR) を使い分ける
  • 条件の順序に注意(厳しい条件から判定)
// 判定順序 if (条件A && 条件B) { // 両方満たす場合(最も厳しい) } else if (条件A || 条件B) { // どちらか満たす場合 } else { // どちらも満たさない場合 }
✅ 解答例フロー
[ { "id": "ex3_inject_danger", "type": "inject", "name": "危険(32度,85%)", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "topic": "", "payload": "{\"temperature\":32,\"humidity\":85}", "payloadType": "json", "x": 150, "y": 80, "wires": [["ex3_function"]] }, { "id": "ex3_inject_warn", "type": "inject", "name": "注意(32度,60%)", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "topic": "", "payload": "{\"temperature\":32,\"humidity\":60}", "payloadType": "json", "x": 150, "y": 140, "wires": [["ex3_function"]] }, { "id": "ex3_inject_normal", "type": "inject", "name": "正常(25度,60%)", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "topic": "", "payload": "{\"temperature\":25,\"humidity\":60}", "payloadType": "json", "x": 150, "y": 200, "wires": [["ex3_function"]] }, { "id": "ex3_function", "type": "function", "name": "複合条件判定", "func": "let temp = msg.payload.temperature;\nlet humid = msg.payload.humidity;\n\nlet isHighTemp = temp > 30;\nlet isHighHumid = humid > 80;\n\nlet result;\n\nif (isHighTemp && isHighHumid) {\n result = \"熱中症警報\";\n} else if (isHighTemp || isHighHumid) {\n result = \"注意報\";\n} else {\n result = \"正常\";\n}\n\nmsg.payload = {\n temperature: temp,\n humidity: humid,\n status: result\n};\n\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 380, "y": 140, "wires": [["ex3_debug"]] }, { "id": "ex3_debug", "type": "debug", "name": "結果", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 550, "y": 140, "wires": [] } ]

演習4: カウンターとN回処理上級

📝 課題:

メッセージをカウントし、5回ごとに集計結果を出力してください。

🎯 要求仕様:

✅ 成功の条件:

💡 ヒント

フローコンテキストの使用:

  • flow.get("count") で値を取得
  • flow.set("count", value) で値を保存
  • count % 5 === 0 で5の倍数を判定
// コンテキスト使用例 let count = flow.get("count") || 0; count++; flow.set("count", count); if (count % 5 === 0) { // 5の倍数のときの処理 }
✅ 解答例フロー
[ { "id": "ex4_inject", "type": "inject", "name": "カウント+1", "props": [{"p": "payload"}], "repeat": "", "crontab": "", "once": false, "topic": "", "payload": "", "payloadType": "date", "x": 130, "y": 100, "wires": [["ex4_function"]] }, { "id": "ex4_reset", "type": "inject", "name": "リセット", "props": [{"p": "reset", "v": "true", "vt": "bool"}], "repeat": "", "crontab": "", "once": false, "topic": "", "x": 120, "y": 160, "wires": [["ex4_function"]] }, { "id": "ex4_function", "type": "function", "name": "5回ごとに出力", "func": "// リセット処理\nif (msg.reset) {\n flow.set(\"count\", 0);\n msg.payload = \"カウンターをリセットしました\";\n return msg;\n}\n\n// カウント取得・更新\nlet count = flow.get(\"count\") || 0;\ncount++;\nflow.set(\"count\", count);\n\n// 5の倍数かどうか判定(剰余演算子を使用)\nif (count % 5 === 0) {\n msg.payload = {\n message: \"5件処理完了\",\n totalCount: count\n };\n return msg;\n}\n\n// 5の倍数でない場合は出力しない\nreturn null;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 330, "y": 120, "wires": [["ex4_debug"]] }, { "id": "ex4_debug", "type": "debug", "name": "5件ごとの結果", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "x": 540, "y": 120, "wires": [] } ]

🎓 9. まとめ

演算子の重要ポイント

⚠️ よくある間違い

📚 次のステップ

演算子の基礎をマスターしたら、以下も学んでみましょう:

🔧 10. トラブルシューティング

よくある問題と解決方法

問題 原因 解決方法
"103" になる "10" + 3 で文字列連結 Number("10") + 3 で数値に変換
常にtrue/falseになる = と == を間違えている 比較は === を使用
NaN が出る 数値でない値で計算 isNaN() でチェック、Number()で変換
Infinity が出る 0で割り算 割る前に 0 でないかチェック
条件が期待通りにならない 演算子の優先順位 括弧 () で順序を明示
undefined との比較 変数が未定義 typeof で型チェック、?? 演算子でデフォルト値

🔗 11. 追加リソース


このガイドが役に立ちましたら、実際のプロジェクトで練習してみてください!
演算子はプログラミングの基礎中の基礎です。

🏠