LoginSignup
2
2

More than 1 year has passed since last update.

CSharp使いがJavaScriptへ乗り換えるためのクイックガイド

Posted at

JavaScriptとC#は基本文法の雰囲気はそんなに遠くないです。
あくまでプログラミング言語としてみた場合、C#ちょっと書ける人がJavaScriptならではの理由でつまづくことって、初級中級レベルでは無さそうです。イラッとすることはたくさんあるかも。

JavaScriptからTypeScriptに入門しようとして苦労した人とそうでなかった人の両方を見たことがあるのですが
静的型付け言語(C#とかJavaとか)の経験者は割と入りやすかったようです。未経験者は結構苦労してました。
そこからの類推なのですがC#からJavaScriptは割と入門しやすい気がしてます。逆は苦労しそうです。。

:four_leaf_clover: お仕事でふだんC#使っているのですがこれからJavaScriptが必要になる雰囲気があるので初学者の後輩に向けて書きました。

:four_leaf_clover: 今Qiitaを見ているブラウザ上からコードのお試しができます。右クリック > 「要素の詳細を表示」で開発者用ツールを出してからコンソールタブへ移動したら、あとはこのページのサンプルコードをコピペするだけで動作確認できます(一部のぞく)

標準出力(Hello, World)

console.log("Hello, World");

ブラウザ上で動かしている場合1には、window.alert() とか document.write() を使ってみるのも面白いでしょう。
console.log() の結果をブラウザ上で確認する場合には、ブラウザ上で右クリックして開発者用ツールを表示する必要があります。

変数宣言

// どれでも動きますよ
let x = 42;
var y = 21 * 2;
const z = "Hello, World";

歴史的ないろんな経緯があって、var は今はあまり使いません。let またはconst を使います。
let は再代入が可能な変数です。const は再代入不可、つまり宣言した瞬間に値を入れないとダメです。
じゃあ全部let でいいじゃん、ということになるかもしれませんがconst 使っておけば意図しないタイミングで値が書き換えられちゃうみたいなことを防げます。
使い分けていきましょう。2

型について

JavaScriptには変数の型がありません。(よく勘違いされますが値の型はあります)

文字列定数

ダブルクォーテーションかシングルクォーテーションで囲った文字列は定数として扱われます。どちらも意味は同じ。
:four_leaf_clover: 通例混ぜません。プロジェクトごとに、どちらかに統一するのが普通です。

if ("aaa" == 'aaa') console.log("yes"); // yes

テンプレートリテラル

バッククォートで囲っても文字列です。このときその中に${}で囲った式は計算された後最終的に文字列になります。
C#の文字列補間式$"Hello, {name}"と同じです。

console.log(`11 * 11 = ${11 * 11}`); // 11 * 11 = 121

const name = 'TomK';
console.log(`Hello, ${name}`); // Hello, TomK

キャスト

変数の型がないのでキャストもありません。3
数値と文字列の変換とかはparse 系の関数を使います。

const n = Number.parseInt("123");
console.log(n + 123); // 246

制御文

for, if, else

FizzBuzzで理解しよう

for(let i = 0; i < 30; i++) {
  if (i % 15 == 0) console.log("FizzBuzz");
  else if (i % 3 == 0) console.log("Fizz");
  else if (i % 5 == 0) console.log("Buzz");
  else console.log(i);
}

雰囲気はC#と同じです。
while switch あたりも似てるので雰囲気で乗り切れるはず

オブジェクト

const obj = {
  a: "alpha",
  b: "blavo",
  c: "charlie"
}

console.log(obj.a); // ドット記法
console.log(obj['b']); // ブラケット記法

オブジェクトは連想配列(辞書Dictionaryとも)っぽい雰囲気のやつです。
C#ではオブジェクトは「Dictionary型とかList型とか色々型がある」みたいな認識あるかもしれませんがJavaScriptにはそんなものはありません。
オブジェクトはほぼ全部Object型です。4

オブジェクトは入れ子もいけます。

const obj2 = {
  tokyo: {
    minato: "akasaka",
    shinjuku: "yoyogi"
  },
  kanagawa: {
    yokohama: "minatomirai",
    kawasaki: "saiwai"
  }
};

console.log(obj2.tokyo.minato); // akasaka

みて気づいた方もいるかもしれませんがこれってJSONと似てますよね。
それもそのはずでJSONはJavaScript由来です。
JSONドキュメントはJavaScriptのオブジェクトとして有効な書式です。

配列とforeach

C#わかれば雰囲気でいけます、、と思ったけど結構違うかも

const arr = [1, 2, 3];
const zipCodes = [
  {"zipCode": "100-0001", "address": "東京都千代田区千代田"},
  {"zipCode": "100-0002", "address": "東京都千代田区皇居外苑"},
  {"zipCode": "100-0003", "address": "東京都千代田区一ツ橋"},
];

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

for(const z of zipCodes) {
  console.log(`郵便番号${z.zipCode}の住所は${z.address}です。`);
}

型がゆるゆるなので配列の宣言の際に「何の」配列なのかを宣言する必要がないです。する術もありません
なので何でもつっこめてしまいます。こういうことはあんまりしない方がいいです
:four_leaf_clover: 馬鹿馬鹿しいと思うかもしれませんが結構よく見かけます。元々C#使ってた人からするとおおっ!?と思いますけど

let numbers = [1, "2", {number: 3}, 4.05};

配列操作(LINQ的な)

const zipCodes = [
  {"zipCode": "100-0001", "address": "東京都千代田区千代田"},
  {"zipCode": "100-0002", "address": "東京都千代田区皇居外苑"},
  {"zipCode": "100-0003", "address": "東京都千代田区一ツ橋"},
];

const searchResult = zipCodes
    .filter(zipCode => zipCode.address.includes("東京都"))
    .filter(zipCode => zipCode.zipCode.startsWith("100-"));

console.log(searchResult);

対応表

中間操作

C# JS
Select map
SelectMany flatMap
Where filter
OrderBy sort
Reverse reverse

終端操作

C# JS
First [0]って書くことが多いけどat(0)もいけそう5
Last at(-1) 5
All every
Contains includes
Reduce reduce
Any some
ToList (なし) JavaScriptの配列操作は配列を返すので、いちいち変換不要

配列操作

配列に要素を足す、取り除く

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.push(11); // 末尾に要素を追加する
console.log(arr.pop()); // 末尾から要素を取り出す
arr.splice(3, 0, 3.14); // 途中に要素を追加したり、途中の要素を変更したりする

関数

function sum(a, b) {
  return a + b;
}

const result = sum(1, 2);
console.log(result); // 3

初歩的な関数はあんまり難しいことはないです
戻り値と引数に型がないことに注意。明示しなくていいし、裏を返せば明示できません。

関数/メソッドを書ける場所

C#ではメソッドを宣言できる場所は決まっていました。(クラスの中でメンバーとして宣言する)
JavaScriptでも同様で、処理フロー内には書きません。トップレベルか、クラスのメンバーとして宣言します。

関数の別の宣言の仕方

このサンプルは上から順番に試した場合にはsum関数が重複してるのでうまく動かないかも
const sum = function(a, b) {
  return a + b;
}

const result = sum(1, 2);
console.log(result);

functionの後に名前を入れるのではなく、無名で関数を作り、それを変数の中に突っ込むというやり方もできます
まあ似たようなものかと思うかもしれませんが、これが可能ということは 関数をオブジェクトとして扱うことができる という意味です。つまり・・

このサンプルはaxiosらへんがインポートしてないしテキトウな書き方なのでうまく動きません
const errorLog = function(e) {
  console.log("エラーが起きました。内容: " + e);
}

const submit = function(text) {
  axios.POST("www.example.com", text); // 中身はてきとう
}

const process(mainProcess, arg, onError) {
  try {
    mainProcess(arg);
  } catch (err) {
    onError(err);
  }
};

process(submit, "hello world", errorLog);

みたいな書き方ができるということです。よく聞くコールバック関数を渡すとかいうのはこういう仕組みを使います。
:four_leaf_clover: まだ聞いたことなくても今後嫌というほど聞くはずです

あとアロー関数の書き方を使うこともできます

このサンプルは上から順番に試した場合にはsum関数が重複してるのでうまく動かないかも
const sum = (a, b) => a + b;
sum(1, 2);

[1, 2, 3, 4, 5, 6, 7, 8, 9]
.map(x => x * x)
.forEach(x => console.log(x)); // 1から9までの数の2乗

クラス

C#と同様普通にクラスを使えます
メンバ変数の宣言とコンストラクタの書式に注意
あとアクセサ(privateとかpublicとか)はありません 最近追加されました。みんな使っているのかはわからないけど

class MyClass {
  a;
  b;

  c() {
    return this.a * this.b;
  }

  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
}

const myCls = new MyClass(1, 2);
console.log(myCls.c()); // 2

比較, Truthy, Falsy

JavaScriptでは == ではなく === を使えとよく言われます。詳細はググってください。

null, undefined

JavaScriptにはnullの他にundefinedとかいう謎な何かがあります。 詳細はググってください。私もよくわかってないので
値が入っていない時によく見ますけどnullとの本質的な違いは本当によくわからんのや・・・

外部モジュール

import

外部モジュールの読み込み
JavaScriptには大別して2系統の言語仕様があります6。処理系で言うとブラウザとNode.jsです。仕様でいうとECMAScriptとCommonJSです。
とりあえずimport 文はECMAScriptの書き方です。

このサンプルはインポート内容とかがテキトウなので動きません
import x from 'xxx';
import { a, b, c } from 'abc';
import x as a from 'xyzjs'; // xと名前がかぶるのでasで呼び方を変えている

export

import文を使って外部モジュールとして読み込み可能にするための構文です。
C#でいうところのpublicみたいなものだと思ってください。

async, await

C#と同様。特にWebアプリを作る時とかは、サーバーとのやり取りを待つ必要があるため多用します。
C#ではasyncな関数はTask を返しますがJavaScriptではPromise を返します。一緒です

:four_leaf_clover: 何を言っているんだという人は無理してついてこようとしなくていいです、非同期の基礎からゆっくりやりましょう

フォームとのやり取り

入門レベルを超えて実践的な内容に入ってしまうので簡単に触れるだけにしておきます。
JavaScriptが活躍する重要な場面はもちろんWebブラウザであり、JavaScriptのコードはhtmlとセットで読み込まれることが多いです。
なのでJavaScriptコードをhtmlに埋め込んで、フォームから情報を受け取って処理を行って表示するまでの流れを見てみましょう

このサンプルはHTMLなのでコンソールに貼り付けても動かないです
<html>
  <script>
    function printSum(){
      const a = document.getElementById("a").value;
      const b = document.getElementById("b").value;

      const sum = Number.parseInt(a) + Number.parseInt(b);

      document.getElementById("result").innerHTML = sum;
    }
  </script>

  <input id="a"></input>
  <input id="b"></input>
  <button onclick="printSum()">SUM</button>
  <span id="result"></span>
</html>

無題23_20220618175838.PNG

:four_leaf_clover: なるべく簡素化しつつこれまで扱った内容だけを使って説明するために、色々と「普通こういう書き方しないよね」みたいものが含まれているんですが
わかっている人は相手にしていないので無視しますね

ポイントになるのは
document.getElementById() を使って文書の中に埋め込まれている要素を取ってきていること
button 要素のonclick 属性で、クリック時のアクションを指定していること

ノリはこんな感じです。
実際には現代ではonclick を使った書き方はしないみたいです。でもVue.jsの@click と書き方が酷似しているので、廃れたとはいえ考え方は悪くないと個人的には思います。
一方でdocument.getElementById() は結構書き方が長ったらしいですよね、この辺のめんどくささを解消してくれるのがVue.jsなどのフレームワークなわけです。これ以上はJavaScript自体の入門レベルは超えるのでここまで!


:four_leaf_clover: 余談。気づいたんですが初学者の人向けの、モダンなJavaScriptの体系的な無料の入門サイトってなくないですか?C#だと未確認飛行Cさんとか超有名じゃないですか。MDNはちょっと難しいし。誰か作ってください

  1. ブラウザ上で動かさない場合: Node.jsとかがあります

  2. 再代入はバグの温床になるからやめろという過激な方もいますのでプロジェクトの方針に従ってください

  3. ちょっと自信ない。。変換はあるけどキャストはないよね?

  4. MDN より。ここでいう「ほぼ」の例外はDateとかFunctionとかErrorとかを指すってことでいいのだろうか、と思いましたが深く調べていないです

  5. MDN より。使ったことありません 2

  6. この辺厳密なこと調べて書いていないので何か気づいた方がいたら教えてください

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2