KeihakuOh / GraphQL_React_App

0 stars 0 forks source link

jsについて #6

Open KeihakuOh opened 2 days ago

KeihakuOh commented 2 days ago

fields: () => ({ ... }) とすることで、フィールドの定義を遅延評価し、相互依存する型同士の参照問題を回避できます。 型が相互に依存している場合(今回のUserTypeとCompanyTypeのようなケース)、フィールドの定義を関数でラップすることで、依存関係が適切に解決されます。

下のようにするとuserTypeは未定義というエラーは出てこない

const CompanyType = new GraphQLObjectType({
  name: 'Company',
  fields: () => ({
    id: { type: GraphQLString },
    name: { type: GraphQLString },
    description: { type: GraphQLString },
    users: {
      type: new GraphQLList(UserType),
      resolve(parentValue, args) {
        return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`)
          .then(res => res.data)
      }
    }
  })
});

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    id: { type: GraphQLString },
    firstName: { type: GraphQLString },
    age: { type: GraphQLInt },
    company: {
      type: CompanyType,
      resolve(parentValue, args) {
        return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`)
          .then(res => res.data);
      }
    }
  })
});
KeihakuOh commented 2 days ago

varとlet

for (var i = 0; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 0);
}

var の特徴:

var は関数スコープです。つまり、ループの中でiを宣言しても、ループが終わった後でも同じ変数iを共有しています。 このため、ループが完了した後に、iは3になっています。 動作:

setTimeoutで非同期処理が登録されますが、全てのsetTimeoutが実行されるのは、ループが完了した後です。 ループが完了した時点で、iは3になっているため、全てのsetTimeoutのコールバックが実行される時点では、iは3です。 結果: 3, 3, 3

ここで、全ての setTimeout のコールバックが実行されるが、すべて同じ i(3)を参照しているため、3, 3, 3 と出力される。

ーーーーー

for (let i = 1; i < 3; i++) {
  setTimeout(function() {
    console.log(i);
  }, 0);
}

let の特徴:

let はブロックスコープです。つまり、ループごとに新しいiが作成され、各ループのスコープ内で独立して存在します。 そのため、setTimeoutのコールバック関数の中では、それぞれのループでのiの値が保持されています。 動作:

setTimeoutのコールバックが実行される時、ループごとに異なるiの値が保持されています。 最初のiが1、次が2です。 結果: 1, 2

実行の詳細な流れ i = 0 で 新しいスコープが作成され、setTimeout が登録されます。このコールバックは i = 0 を保持しています。 i = 1 でまた別の新しいスコープが作られ、setTimeout が登録されます。このコールバックは i = 1 を保持しています。 i = 2 でも同様に、別の新しいスコープが作られ、setTimeout が登録されます。このコールバックは i = 2 を保持しています。 ループが完了すると、各 setTimeout が順に実行され、それぞれ異なる i の値を出力します。

ーーーーー

ブロックスコープ(let、const)

if (true) {
    let x = 10;  // `let` はブロックスコープ内でのみ有効
    console.log(x); // 10
}
console.log(x); // エラー: `x` はブロックの外では定義されていない

//let はブロックスコープなので、ifブロック内でのみxが有効です。

関数スコープ(var)

function example() {
    if (true) {
        var y = 20;  // `var` は関数スコープ内で有効
        console.log(y); // 20
    }
    console.log(y); // 20: 関数全体で `y` は有効
}
example();
var は関数スコープなので、ifブロックの外でも関数内で有効です。