フリーランス チャレンジ!!

読者です 読者をやめる 読者になる 読者になる

フリーランス チャレンジ!!

週休4日制に俺はなる!

【JavaScript】気をつけて オブジェクトの代入は参照渡し

f:id:ksakae1216:20081121175121j:plain

みなさん、コウタロウです!!

 

今日はタイトルについて。

 

 

結論から

JavaScriptの代入は参照渡しです。

 

例)

var obj1 = { aaa: 'rei' };
var obj2 = obj1

obj2.aaa = 'henkou';

console.log(obj2.aaa);   //henkouと表示される
console.log(obj1.aaa);   //あれ!? henkouと表示される

 

ハマりポイント

そういえば何の根拠もなかったが、参照渡しだとは思っていなかった。

 

現場の仕事でAngularJsのローカルストレージ、セッションストレージを使用しています。

 

ログイン画面を開きログインするとメニュー画面があり、メニュー画面で各ボタンを押下すると別タブにて遷移先画面が開きます。

 

別画面(別タブ)でログインした時のユーザー情報を使おうと思ったらセッションストレージはタブが変わると共有できません。

 

それなのでログインした時のユーザー情報は一旦セッションストレージからローカルストレージに代入して別タブにて、ローカルストレージからセッションストレージに代入し、ローカルストレージの内容はNullにしていました。

 

つまり、こんな感じ

【メニュー画面】

localStorage.userInfo = sessionStorage.userInfo;  //ローカルストレージに代入

 

【遷移先画面(別タブ)】

sessionStorage.userInfo = localStorage.userInfo;

localStorage.userInfo = null;

 

これで無事、別タブにユーザー情報を渡すことができ、メニュー画面もユーザー情報を保持していると思っていました。

 

でも画面動かすと、別タブで参照渡しされたユーザー情報を消してしまったため、メニュー画面でユーザー情報が参照できなくなり、エラーとなる。

 

オブジェクトの代入が参照渡しだとわかるまで2時間くらいかかってしまいました。。。

 

回避策

参照渡しではなく、ディープコピーをすることにしました。

 

【メニュー画面】

//ディープコピー

localStorage.userInfo = angular.copy(sessionStorage.userInfo); 

 

【遷移先画面(別タブ)】

sessionStorage.userInfo = localStorage.userInfo;

//localStorage.userInfo = null;  ディープコピーでもnullにするとメニュー画面でもユーザー情報が参照できなくなるのでこの処理もコメント

 

ディープコピーにすれば別タブでローカルストレージの内容を消しても大丈夫かと思いましたが、消したらメニュー画面で見えなくなったのでやむえず消す処理をコメント化。

 

 

最後に

一つ一つの積み重ね。

 

今回、わかるまで2時間かかりましたが、今回の経験を積むことにより自分のスキルが更に高まりました!!