LoginSignup
s_kajigo
@s_kajigo (kaji shogo)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

アロー関数とfunction関数の違い

あるプログラミング学習サイトでfunctionを使用して書いていたプログラムをアロー関数で書き換えていた際に、もともと動いていたものが動かなくなりました。

以下記載したコードです。

async function getData() {
  const userList = [
    { id: 1, first_name: '優', family_name: '大木', affilication: 'TechTrain', is_student: false },
    { id: 2, first_name: '太郎', family_name: '山田', affilication: 'HogeHoge大学', is_student: true }
  ];

  const result = await new Promise(resolve => setTimeout(() => resolve(test(userList)), 3000));
  return await result
}

function test(data) {
  data.map(tell)
  function tell(data) {
    const full_name = data.family_name + " " + data.first_name;
    data.full_name = full_name;
  }
  return data;
}

学生のフルネームを3秒後にブラウザに表示するプログラムです。
function test以下の部分をこのように書き換えました。

test =(data)=>{
    data.map(tell)
    tell =(data)=>{
    const full_name = data.family_name + " " + data.first_name;
    data.full_name = full_name;
  }
  return data;
}

するとtellが定義されていないとエラーが表示されました。
data.mapの前にtellを定義することで解決しました。

解決したいこと
1、なぜfunction関数では動いて、アロー関数では動かなかったのか
2、アロー関数では使用するメソッドは使用前に定義するものなのか
3、2だとすればnew Promise内で呼んでいるtest関数はなぜエラーにならないのか

文法をそれぞれ調べたり、違いについても調べましたが答えには辿り着けていません。
初歩的な質問ですが、ご教授いただければ幸いです。

0

2Answer

1、なぜfunction関数では動いて、アロー関数では動かなかったのか

functionによる関数の定義のタイミングとアロー関数による定義のタイミングが異なるからです
ただし、プログラミングは順次実行が多いので前もって定義しておく方が一般的かと思いますので、
基本的に前もって定義しておくことに慣れておいた方がいいかと思います。
(プログラムを追いかける場合も上で定義されたり下で定義されたりすると一貫性がなく読むのが辛くなると思います)

2、アロー関数では使用するメソッドは使用前に定義するものなのか

1に記載したので省略

3、2だとすればnew Promise内で呼んでいるtest関数はなぜエラーにならないのか

getDataが呼び出されているタイミングによります。
testまで定義された後、getDataが呼び出されたのであれば当然エラーにはなりません
おそらくですが、即時実行にした場合はエラーになると思います

PS.

async function getData() {
  const userList = [
    { id: 1, first_name: '', family_name: '大木', affilication: 'TechTrain', is_student: false },
    { id: 2, first_name: '太郎', family_name: '山田', affilication: 'HogeHoge大学', is_student: true }
  ];

  const result = await new Promise(resolve => setTimeout(() => resolve(test(userList)), 3000));
-   return await result // ←awaitの意味がない
+   return result
}

testをアロー関数に直すとこのレベルでもいいかなと

const test = (data) => data.map((d) => ({
  ...d,
  full_name: `${d.family_name} ${d.first_name}`,
}));
2

Comments

  1. @s_kajigo

    Questioner
    とても分かりやすく、知りたかったことがよく理解出来ました!
    また、これからの参考になる部分まで根拠を添えて教えていただき大変勉強になりました。
    本当にありがとうございます。

まずちゃんとした変数宣言セミコロンを付けるクセを付けましょう。
「自動セミコロン挿入」という末尾にセミコロンがなくてもブラウザ側でセミコロンがあるように解釈しますが、どちらかに等するなら兎も角、混在してはなりません。

変な省略の仕方はエラーの原因となります。

アロー関数とfunction関数の違いについてはここで書きません。検索すれば既に秀逸な記事がいくつも出てくるからです。

なぜfunction関数では動いて、アロー関数では動かなかったのか

前者では関数宣言をしているのに対し、後者は変数宣言がなされてない(結果的に未定義変数扱いとなってる)

2、アロー関数では使用するメソッドは使用前に定義するものなのか

はい、名前を持たせたいのであれば変数宣言しなければ成りません。

アロー関数に関しての知識がないように見受けられるのでその辺も学習なさってください。

3、2だとすればnew Promise内で呼んでいるtest関数はなぜエラーにならないのか

testを変数宣言しなかったため、ブラウザ側で勝手に変数宣言されてるからです。

つまりブラウザ側の解釈は次のようになります。

+++ var test = (data) => {
+++	var tell;
+++	data.map(tell);// 当然ながら空の変数である
	tell = (data) => {// これ以降よりtellにアロー関数が代入されている
		const full_name = data.family_name + " " + data.first_name;
		data.full_name = full_name;
+++	};
	return data;
}

この辺りのカラクリはvar文を見ると良いでしょう。

冒頭でも書きましたが変な省略の仕方はブラウザの勝手な解釈があるため地獄です。
変数宣言・初期化などはしっかりなさってください。

2

Your answer might help someone💌