LoginSignup
2
0

More than 3 years have passed since last update.

TypeScriptでobjectの値の参照渡しでコケた時の回避方法

Posted at

何をしようとしたか

特定の項目が同じ値のままUserを使いまわそうとした。
今回の例だと User.age

entities/User.ts
export class User {
  name: string;
  age: number;
}
typescript/main.ts
import { User } from "./entities/User";

export const main = () => {
  let users: User[] = [];

  let user: User = { name: "alpha", age: 20 };
  users.push(user);

  // nameのみ変更
  user.name = "beta";
  users.push(user);

  console.log({ users });
};

main();

求めていた結果

{ users: [ { name: 'alpha', age: 20 }, { name: 'beta', age: 20 } ] }

実際に出てきた結果

{ users: [ { name: 'beta', age: 20 }, { name: 'beta', age: 20 } ] }

betaくんが2人になってる…

回避手段

調べたらjavascriptはobjectの場合、値の参照渡しを行うらしい

なら毎回新しいobjectを生成すればいいのかと思った

丁度nestjsを使用していたので、class-transformer/plainToClassを使用することにした

npm i class-transformer
main.ts
import { plainToClass } from "class-transformer";
import { User } from "./entities/User";

export const main = () => {
  let users: User[] = [];
  let user: User = { name: "alpha", age: 20 };
  users.push(plainToClass(User, user));
  user.name = "beta";
  users.push(plainToClass(User, user));

  console.log({ users });
};

main();

実行結果

{  users: [ User { name: 'alpha', age: 20 }, User { name: 'beta', age: 20 } ]}

求めている形で返ってきた

感想

objectの取り扱いには気をつけよう
そもそも使いまわしたい部分に対して処理をちゃんと書けばこうならなかったはず
とりあえず動かしたい精神で書いてたら死んだ

参考

[Qiita]JavaScriptに参照渡し/値渡しなど存在しない

2
0
1

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
0