1 名前:デフォルトの名無しさん mailto:sage [2016/05/22(日) 19:51:33.37 ID:WwOYSBmy.net] JavaScript を自ら学ぶ人のための質問スレッドです。 >>2-4 のテンプレを読んだ上で質問してください。次スレは>>950 が>>2 のテンプレ案(本スレで改善案があれば考慮)を元に立ててください ■質問を書く上で (1) 煽り、コード制作依頼等、人を不快にさせる投稿はご遠慮下さい。公序良俗を守った応対を心がけてください。 (2) 他の人に迷惑をかけるスクリプトの質問はご遠慮ください。 (ブラクラ、[戻る], [閉じる], [クリック] の妨害、画面占有など) (3) 質問者及び議論を行う人はメール欄を空欄にし、名前にレス番を入れることを強く推奨します。回答者はなりすましを判断できませんので、なりすましが現れても自己責任となります。 (4) 常に自発的に調べる心構えを持ってください。 具体的には「自分で調べてから質問する」「回答をもらってわからない単語があればGoogle検索してみる」など。 わからない内容を代わりに調べてくれる回答者をお望みの方は余所で質問してください。 (5) 出来るだけ一般的な用語を使用してください。脳内オレオレ用語は混乱の元です。 (6) 出来るだけサンプルコードを掲示してください。言葉による説明は行き違いが生まれる場合があります。 ※必ず「問題の事象が再現されること」を確認してください。 必要な部分だけ切り出したつもりで現象が再現できていなかったケアレスミスがしばしば見られます。 (7) サンプルコードに HTML が含まれる場合は validator.w3.org/ で [Check] してみてください。 (8) 質問を具体的かつ詳細に書くと回答を得られやすいです。>>2 の質問テンプレートを活用してみてください。 (9) 時にはあなたが望む「答え」だけでなく、「意見」などが寄せられる場合もあります。
596 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 00:51:30.61 ID:CJz8oq6+.net] 後学のためにID真っ赤にしてる方々の書いた素晴らしいスクリプトを見せてくださいよ
597 名前:576 mailto:sage [2016/06/12(日) 00:51:41.20 ID:AMLyjVO9.net] >>578 お前のことだったんかw いきなりなんか言われて意味不明だったわ。 えーと何の話だっけ? 同期命令が使える言語で、 sleep(1000) console.log(1) sleep(1000) console.log(2) sleep(1000) console.log(3) と書きたくなるようなコードを、ネストして書くだけでも苦痛なのに、これを関数に分解して function Main_1() { sleep(1000) console.log(1) } function Main_2() { sleep(1000) console.log(2) } function Main_3() { sleep(1000) console.log(3) } とかやりたくないわけでw あと関数なのに、大文字から始めってる時点で、経験不足だってことがわかるよ。 念の為に言っておくと、上のMain_1とか言うのは俺がいい出した名前じゃないからねw
598 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 00:52:45.85 ID:AMLyjVO9.net] >>579 俺は何回も書いてるよ。 >>546 とか読んでみな。(俺が>>546 という意味ではない)
599 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 01:26:35.68 ID:npk74fIw.net] はいはい自演乙。 自演じゃないならレベルの高い>>578-581 の間で色々解決できるだろうから頑張れ。
600 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 01:33:50.33 ID:AMLyjVO9.net] > 自演じゃないならレベルの高い>>578-581 の間で色々解決できるだろうから頑張れ。 自演じゃないぞw 解決できるだろうけど、その前に何も解決すべき 課題が出てないじゃないかw そして、俺とお前は他人だろ? その理屈ならいろいろ解決できるだろうな。 何か言ってみろ。俺は手伝わないがwww
601 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 01:40:01.79 ID:m2Zib5nl.net] あ?なんだこのゴミみたいな木っ端は 最低でも1000行以上あるプログラムとして成立してるもんもってこいや
602 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 01:43:07.89 ID:npk74fIw.net] >>583 じゃあとりあえず>>578 の疑問に答えてやれよ > 相互に呼び出し合う事のある関数なんかどういう順序で記述するんだろ。 > イベンハンドラやら、タイマーのハンドラは、どの順序なのかな。 厳密にはこれは質問ではないから、「俺がどう書くか」の予想でもいいぞ。 とにかくお前らで色々話をしてみろ。 面白そうなら俺も加わるし、他も加わってくるだろう。 どうでもよければ無視されるだけだ。
603 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 02:01:39.12 ID:AMLyjVO9.net] >>585 どうせ質問に答えても自演じゃないって認めないんだろw まあ質問じゃないとお前もわかってるようだから、それにレスしろと いうならば、レスするのは何の問題もない。 >>578 > 相互に呼び出し合う事のある関数なんかどういう順序で記述するんだろ。 > イベンハンドラやら、タイマーのハンドラは、どの順序なのかな。 全くだなw 必ずしも上から書けるわけがない。 関数を呼び出される順番に書くとか言っているやつは馬鹿じゃないだおろうかね どういう順番で書くかは、ばらばらで人によってはアルファベット順ってこともあるだろう。 だから必要もないのに小さな関数に分けるなんて論外。 一つの関数にし、ネストがいやだからPromiseというのが使われるようになった。 この件に関しては、俺は>>578 と同じ意見だろうな
604 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 02:36:10.54 ID:npk74fIw.net] >>586 > この件に関しては、俺は>>578 と同じ意見だろうな そりゃ同一人物だからなw まあ、人殺し君も多投するタイプだから、待ってればレスが返ってくるはずだ。 そして本当に別人なら、色々意見交換すれば相違点が発見できるだろう。 それは俺関係なしにいいことだから、やってみることだね。
605 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 02:56:48.44 ID:hCgFiHr7.net] >>587 同一人物とかよくわからんな。 俺が連投するのは暇だからで、まともに過ごしてる時はそれなりにしか書かんけど。 10日間際は忙しいからな。 まさか本気で同一人物だと思ってたら笑えるww
606 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 03:17:12.70 ID:hCgFiHr7.net] >>586 うむ。アルファベット順ならまだマシだけど。 台帳に書いてある順とかちょっとびっくりする会社もあるからな。どことは言わんけど。 多分業務経験ない奴は笑うだけだが、 実務やってれば「NDA結ばないとリバースエンジニアリングすら難しい」という人間minifierだったりする。 必要に応じて関数は分けるべきというより、むしろ、関数は射影的であるべきだと思う。 コールバック関数のネストを「関数と関数を繋いでる」と単純に誤解して悪手だと思ってほしくないのが、 本来は関数と「関数を引数に取る関数」を定義して、「関数を引数にとる関数」に関数を食わせるが為の手段を逆に見た結果、「コールバック」って姿に見えてるだけ。 だから、yieldとジェネレーターを使おうが、Promiseを使おうが、本来は何一つ定義が変わってる訳でも、処理が変わってる訳でも無い。 関数に関数を食わせて値を取り出してる。 ・水を冷やして出来た物を、回転する鉋で削って、皿に落とし入れたもの、 ・皿で受け止めた、回転する鉋で削られた、冷やされた水、 ・回転する鉋で水を冷やして出来た塊を削り、皿に落としたもの は全部主題が同じもの。 水を冷やす、という関数と水を、値として「氷」と扱おうが、 かき氷機を「『水を冷やした物』削り機」と展開しようが、とう扱うかは使い方次第。 そこに、ニーズ外の要件なんて無いの。扱いにくいとかどうでもいいんよ。 また、undefinedの時と同じ勘違いしてるけどさ。 水→機械A→中間生成物→機械B→製品、 というシーケンスであらわすのが正しいのか、 ((水→機械A)→機械B)→製品、とフローで合わすのかは瑣末すぎるほどの差。 しかし、言われてるのは俺じゃないが、関数を大文字から始めると経験不足なんだwww C20年目かもしれんけどな、そういう人はww
607 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 03:21:29.67 ID:hCgFiHr7.net] こいつ、言われたくないことを人に言って安全圏に逃げたいだけなんだろうなぁ。ユング的なシャドウをもう少し悪く歪めたものが見えるわ。 voidとか、岡部健みたいな感じの破綻者に対して憧れてる人間、くらい性根がさもしい。
608 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 09:01:52.07 ID:AMLyjVO9.net] >>587 だから同一人物じゃねーよw
609 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 09:04:46.11 ID:AMLyjVO9.net] >>589 > しかし、言われてるのは俺じゃないが、関数を大文字から始めると経験不足なんだwww JavaScriptのコーディング規約はいくつもあるが、どれも関数は小文字で始める。クラスは大文字。 JavaScriptの経験があるなら、これに従ってるはずなので 見た瞬間気持ち悪さを感じるものだよw
610 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 09:10:26.75 ID:AMLyjVO9.net] >>589 > だから、yieldとジェネレーターを使おうが、Promiseを使おうが、本来は何一つ定義が変わってる訳でも、処理が変わってる訳でも無い。 処理が変わってるわけでもない・・・ならば 読みやすい方がいいだろ? 逆に考えれば、どんなに読みづらく書いても 処理が変わっていないというコードにすることはできるだろう? 読みづらくても処理が同じならいいと言うのか? そうではないだろう。 コードっていうのは書いて終わりじゃない。修正するもの。 むしろ読むほうが多いので、書くよりも読むほうが大事。 だから「可読性」という言葉がある。「可書性」という言葉はない。 > そこに、ニーズ外の要件なんて無いの。扱いにくいとかどうでもいいんよ。 俺はいまだかつて「時間的に早く書けて修正も簡単で、メンテナンスにかかるコストが低い」 という要件がなかったことはないぞw どんなプロジェクトでも安く仕上げることは、暗黙的に含まれてる要件だ。
611 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 13:15:07.43 ID:npk74fIw.net] 別人であればもっと議論が深まるはずだよな。 みんな見てくれてるから、せいぜい頑張れ。
612 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 13:19:20.40 ID:AMLyjVO9.net] どうあっても別人と認めたくないようだ(笑)
613 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 13:20:50.61 ID:AMLyjVO9.net] あ、なるほど。話が進むと今度は 一人だから意図的に会話できる。 それが自作自演の証拠って言うつもりだなw
614 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 15:04:26.78 ID:npk74fIw.net] いやきみ(ら)にとっては俺はただの馬鹿なんだろ。 だったら俺を引っ張り出す方向のレスを付けること自体おかしいだろ。 ガン無視してくれよw いずれにしても、君らが「別人」かどうかは皆が判断することであって、 俺が「自演」主張しても、逆に君らが「別人」主張しても意味無いんだよ。 どちらがキチガイかは皆が判断してくれる。 そして一つアドバイスをするなら、君のキャラなら>>592 は 「え?お前偉そうなこと言っている割には『大文字』のルールも知らないんだwww」 と煽るべきだった。キャラを変えると自然な自演に見えない。 君も煽りで相手を引き出すキャラなんだし、 このレスなら人殺し君のキャラなら確実に食いついてくるし。 本当に別人なら、君らが会話すれば君らにとっても得る物があるはず。だからもっとやればいい。 いちいち俺に対してキョロキョロしたり、 或いはここに来て会話を終わらせる方向にキャラ変更するのは不自然だ。 はい続きをどうぞ。
615 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 16:27:25.35 ID:9HFtYPb0.net] その人殺し君とかいうのに論破されちゃって 悔しくて大ハッスルしてるの?
616 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 16:54:18.02 ID:hCgFiHr7.net] >>592 そりゃ、javascriptの規約はいくらでもあるだろうけど、 javascriptの規約しか知らないどころか、ありえないような口ぶりで話してたからねw なんかからトランスパイルするなら、こうなるだろうな、って考えたりしないんだ、って感じ。 >>593 もちろんそう。 しかし、読みやすいのと書きやすいのと、定義しやすいのはそれぞれ別の概念だから、そういう意味では可読性に相当する単語は、独立性とか、依存度とか、抽象度とか 見方次第でいくらでも変わるものじゃないか? 安くあげる事より、致命的な不具合を出さない事の方が求められるプロジェクトしかやってないからな。 正直、安くなくても売れるから。 安くないほうが売れるとも言えるレベルで。 >>597 お前ほんと何と戦ってんの?
617 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:20:47.80 ID:npk74fIw.net] >>599 > わざとこの態度だからなぁ。 (>>327 ) 煽っていくスタイルプリーズ
618 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:39:15.05 ID:AMLyjVO9.net] > なんかからトランスパイルするなら、こうなるだろうな、 なんでそんなコード書くの?www
619 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:40:36.87 ID:z4XaqaSO.net] function f(a) { let t = a; t[0] = 1; console.log(a); console.log(t); } let a = [0]; f(a); これaも[1]になっちゃうんですが ES2015とか新しい書き方で配列をコピーする方法ありませんか?
620 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 19:41:46.51 ID:AMLyjVO9.net] >>597 > どちらがキチガイかは皆が判断してくれる。 お前がキチガイだって俺は判断したよwww
621 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 22:24:47.44 ID:QKWa7och.net] 芝生くっつけるやつにろくなのはいないってのは間違いなさそうだ
622 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 22:34:59.19 ID:npk74fIw.net] >>601 馬鹿にはちゃんと安価付けろ。気づいてもらえないぞ。 てかお前もちゃんと煽れよ。 >>599 >>601 は>>599 宛だぞ。 おーい。煽られてるぞー。
623 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 22:46:30.04 ID:xguVhByI.net] そりゃ別人なんだから、煽りもするわwww
624 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 23:31:28.41 ID:GjxFekK/.net] >>602 concat
625 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 23:34:06.35 ID:xguVhByI.net] shallowコピーの場合はconcatでいいよね。 最初は?ってなるけど、知ってしまえば簡単に覚えられるし。 なんらかのdeepコピーの場合はライブラリ使うしか無いかな?
626 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 23:54:06.37 ID:npk74fIw.net] いやシャローコピーは slice() だと思うが。
627 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 23:56:00.26 ID:hCgFiHr7.net] >>605 お前、脳みその代わりにババロア詰まってて、しかも微妙に機能してんじゃねえの? 一番煽られてんのはお前だと思うんだけどw 恥ずかしくねえのかな。。
628 名前:デフォルトの名無しさん mailto:sage [2016/06/12(日) 23:57:34.48 ID:hCgFiHr7.net] >>608 JSON.parse(JSON.stringify(obj)) が、一番手軽で早い。
629 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 00:05:59.69 ID:6Ot446qT.net] >>611 関数コピーできない。 日付がおかしくなる。 undefinedが消える。 使えないねw
630 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 00:15:43.00 ID:rTAmnA9g.net] >>612 値をコピーするなら十分でしょ。 関数をコピーとか必要性がわからんし、 undefinedが消えるって、元からundefinedだったんだから、消えてないでしょ。 undefinedが消えるってのは、undefinedで無くなるときだよ。 お前の頭が使えねえなぁ。
631 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 00:15:53.62 ID:+G6yi6vX.net] let の宣言場所について質問させてください for文の中でのみ使う変数を let で宣言しようとしたら、forの中と外どちらで宣言したほうがいいんでしょうか
632 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 00:32:34.63 ID:6Ot446qT.net] >>613 > 値をコピーするなら十分でしょ。 勝手に決めるな。 日付がおかしくなる問題は解決できてないし、 undefinedが消えるっていうのは、キーが無くなるんだよ。 まったく使えないって言ってるだろ
633 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 00:40:16.01 ID:6Ot446qT.net] >>614 どうするのが一番可読性が良いかを考えれば自ずと答えは出る。 可読性を高くするには、頭の中で覚えておくコードを少なくするということでもある。 だからより小さい範囲、つまりfor文の中で書くのが良い。 ただし、for文の行でいろいろ書くなよ?w for (let i = 0, l = array.length; i < l; i++) for文の行でやるのは多くてもこれだけ(インデックス用の変数と終了条件)だ for (let i = 0, l = array.length, foo, bar, baz; i < l; i++) なんてfor文とは関係ない変数を宣言しないように。 言い換えると、変数に代入しないletはやってはいけないってこと。 let v = 0; // OK let v; // NG またletではなくconstを使ったほうが良いぞ constは再代入が不可能になる。つまり変数に入れた値を変えることが出来ない。 それでプログラミングが出来るのか?って思うかもしれないができるんだ。 関数型プログラミングの考え方を取り入れると殆どconstでよくなる。
634 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 01:17:56.81 ID:+G6yi6vX.net] >>616 むむむ・・・ インデックス用の変数でも終了条件でもないです 後で見たときに何をしているか分かりやすいように、計算途中の値に名前をつけて一時変数に入れていました forの試行毎に新しい計算値が入ります
635 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 01:49:05.39 ID:6Ot446qT.net] >>617 つまりこういうことでしょう? for(let i = 0; i < 10; i++) { let value = i * 10 console.log(value); } 当然forの中だよ。中でしか使わないんだから。 そしてこれはconstに置き換えられる。 for(let i = 0; i < 10; i++) { const value = i * 10 console.log(value); } ループ毎に新しく作られるからだ。 このconst valueをforの外に置くことは出来ない。
636 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 02:07:05.34 ID:LLEcmK37.net] es2015で()=>をつかえばthisの挙動を変更できるのに なんでjavascriptでdeep copyができないのですか? }
637 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 02:13:16.73 ID:+G6yi6vX.net] >>618 ありがとうございます! forの中に引っ越します varに慣れていたので繰り返し処理のなかで宣言するのに違和感があったんですよね
638 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 02:41:54.70 ID:6Ot446qT.net] 俺はvarのときからforの中に書いていたけどね。 そこだけでしか使わないし、別に文法エラーでもなんでも無いんだから。
639 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 06:18:58.38 ID:o3uO7eJP.net] >>615 キーが無くなるのと、キーに対応する値にundefinedが入ってるのは同値だろ。 だから、undefinedを代入してる!みたいな勘違いしたのかな?頭おかしいのかなw 日付がおかしくなるって具体的にはどう言うこと?エポックがズレるみたいな話では無くて、型が誤解されるみたいな話なら苦笑いだな。 >>616 変数に代入しないlet、では無いんじゃねえの? 仮宣言みたいなもんで。
640 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 07:23:07.35 ID:+G6yi6vX.net] スコープ先頭での let a; がダメとなると、スコープ後半
641 名前:になってから代入する値が確定するケースではどうしてるんでしょう? コード修正時にtemporal dead zoneによるミスを起こし易いので、スコープ途中でlet宣言する場合は、明示的に新たにブロックスコープを作ったほうがいいと書いてあるのをどこかで読んだんですが、 最後まで使う変数にそれをするとスコープのためだけにネストが深くなってしまって気持ち悪いです [] [ここ壊れてます]
642 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 07:33:47.84 ID:ZIxcBfsq.net] >>623 let a=nullで宣言しておいたら?
643 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 09:10:57.92 ID:6Ot446qT.net] >>622 > キーが無くなるのと、キーに対応する値にundefinedが入ってるのは同値だろ。 違うぞw keysで出力されるもの見てみwww
644 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 09:47:02.30 ID:uHiiHky6.net] 普通にブロック内に書けばいいんじゃないの? わざわざブロック使えなんていうなら、関数全体で同じことしてるvarだって先頭で全部明示しろってなると思うんだけど
645 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 09:57:57.31 ID:CfEi32hJ.net] >>612 が指摘している問題はおそらく、こういうこと var obj = {fn: function fn () {}, date: new Date, undefined: undefined}; console.log(obj); console.log(JSON.stringify(obj)); // "{"date":"2016-06-13T00:45:07.522Z"}" console.log(JSON.parse(JSON.stringify(obj))); // {"date":"2016-06-13T00:45:07.522Z"} var array = [function fn () {}, new Date, undefined]; console.log(array); console.log(JSON.stringify(array)); // "[null,"2016-06-13T00:48:58.483Z",null]" console.log(JSON.parse(JSON.stringify(array))); // [null, "2016-06-13T00:52:23.947Z", null]
646 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 10:10:14.80 ID:CfEi32hJ.net] JSON.stringify の一番の問題は new Object, new Array 以外の Object 型を扱えない事 new Date なら String 型に変換されるだけだから new Date し直す方法がある(ただし、参照は失われるので参照比較できなくなる)が、それ以外はどうしようもない function Person (name) { this.name = String(name); } var obj = {person: new Person('太郎')}; var obj2 = JSON.parse(JSON.stringify(obj)); console.log(obj); // {person: Person {name: "太郎"}} console.log(obj.person instanceof Person); // true console.log(JSON.stringify(obj)); // {"person":{"name":"太郎"}} console.log(obj2); // // {person: Object {name: "太郎"}} console.log(obj2.person instanceof Person); // false 今のところ、deep copy する標準関数はないので Object.assign を使って自前で deep copy 関数を作るのが妥当
647 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 10:57:57.06 ID:ZIxcBfsq.net] >>625 あのさ、keysで定義されていてもその中身はundefinedなんだろ? なら、データとしての扱われ方として、同じだと思うんだけど。 キーがある事が大切であれば、キーを列挙したもの、というデータがあるべきだと思うんだけどどうなの? >>628 あーなるほど、そういうことか。 参照を失わせるために、そういう事するんだから、であればそのオブジェクトの.toJSONを定義してやるべきだろうね。
648 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 11:55:17.37 ID:CfEi32hJ.net] >>629 > あのさ、keysで定義されていてもその中身はundefinedなんだろ? 横から口を出すが、hasOwnPropety の結果が異なるから同じではない 「undefinedを代入する設計が筋が悪い」といわれればその通りだが、「同じ」ではない 実際、プロパティの存在チェックなら obj.prop !== undefined よりも obj.hasOwnProperty('prop') を使うべきだ var obj = {undefined:undefined}, obj2 = {}; console.log(obj.hasOwnProperty('undefined')); // true console.log(obj2.hasOwnProperty('undefined')); // false > 参照を失わせるために、そういう事するんだから、であればそのオブジェクトの.toJSONを定義してやるべきだろうね。 プリミティブデータの倉庫として使うなら JSON.stringify で良いが、new Object, new Array 以外は参照を失わせるべきではないのでは? >>628 でいえば、new Person('太郎') を {name: '太郎'} に書き換えるメリットがない
649 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 12:22:56.73 ID:CfEi32hJ.net] > 参照を失わせるために、そういう事するんだから、であればそのオブジェクトの.toJSONを定義してやるべきだろうね。 ひょっとして、new Person する為の拡張構文をJSON に追加してやるといいたかったのだろうか 私が deep copy するのは構造を書き換えたいが、元の構造も残したい場合だからデータそのものは元のままでいい new Person('太郎') はたった一人の太郎であり、同名の太郎を作ってもらっては困る 同名オブジェクトを作ると taro === person の比較が出来ず、person instanceof Person && taro.name === person.name のようにダックタイピング的に比較しなければならない こうなるともう new Person を定義した意味がなく、{name: '太郎'} を生成したのと大して変わらない
650 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 13:52:54.74 ID:KnYKOJ/M.net] >>630 あー、わからんでもない。 undefinedを値として使う、ってニーズがあれは、それもまた真なんだろうな。 そうなると、assignでもなくオブジェクト毎にちゃんとcloneを実装すべきって感じか。 >>631 ちょっとまって、それはdeepcopyでは無いんじゃないの? ただの参照の張替えじゃないか。 比較するのであれば、それはequals的なメソッドを作るか、諦めて、stringifyした物同士が同じになるかを比較すべきだろ。
651 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 17:10:28.33 ID:CILZ2bdj.net] >>632 {}, [] は deep copy する [{person: new Person('太郎')}, {person: new Person('一朗')}] 逆に new Person を deep copy したいと思う状況が分からない new Date も関数も期待通りに動かないわけで汎用性が大きく犠牲になっていると思うが…
652 名前:デフォルトの名無しさん [2016/06/13(月) 17:51:17.99 ID:u+uz+gNL.net] ボタンをクリックしたいのですがどう書けばいいかわかりません>_< ソースはこれです↓ i.imgur.com/IQLz1Kp.jpg
653 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 17:52:47.17 ID:viWjyZUM.net] 変数宣言って同じ人でもいまいち一貫性が感じられないんだけどさ はるか遠くで使うのに頭に全部羅列してるかとおもいきや次は使う直前に書いてたり そうしなきゃいけない時ももちろんあるけど、特にそういう理由も見受けられないのもいっぱいある あまり詳しくないんだがなんか意味あるのああいうの
654 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 18:30:36.62 ID:K+DNMsci.net] >>633 状況がわからない、とか言ってちゃぶ台返しされても。。 deepcopyの話じゃないの? それはシャローコピーそのものじゃん。。一番上っ面だけコピーするって。 Personをdeepcopyしたいって要件ならいくらでもあるじゃん。 オブジェクト変更するから、変更前の「前回オブジェクト」を持っておきたいとか、 保存ボタン押すときに、保存の必要性あるか確認したいから、オブジェクトと退避オブジェクトを比較したい、その退避オブジェクトを作るとか。
655 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 20:36:13.44 ID:WO2lddk8.net] private変数っぽくしたいときにこうするのってどう? var Foo = function () {this.private = {};}; Foo.prototype.getBar = function () {return this.private.bar;}; Foo.prototype.setBar = function (b) {this.private.bar = b;}; var foo = new Foo(); { let _baz; foo.getBaz = function () {return _bar;}; foo.setBaz = function (b) {_bar = b;}; } 後者はインスタンスごとにgetter/setterをクロージャにしなきゃいけなくて不満。 前者はfoo.private.barで手が届いちゃうものの、意図は明確でそれで十分な気が。 private変数っ「ぽく」したいだけの場合、前者の方法はどう? みんなどう思う? あとjavascript界隈に既に、こういう「ぽく」したい場合のイディオムってある?
656 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 21:22:27.21 ID:pgYO3XjB.net] to infinity and beyond
657 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 22:52:41.14 ID:O5DunmIw.net] >>636 だから、{}, [] は deep copy するといっているのだが 次の構造は正しくdeep copyされる [[[1], [2]], [[3], [4]]] {a: {1: true}, b: {2: false}} 一口にdeep copyといってもいろいろ問題があるわけで「この問題にあなたはどう考えているのか?」 - 関数はdeep copy出来ない(そもそも、スコープが変わったら動かなくなる可能性がある) - customコンストラクタはdeep copy出来ない - その他、Array, Object以外のdeep copyも難しい この問題は個々がdeep copyする状況によって解決策が変わるだろうからあなたの考えがな聞きたかった
658 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 22:57:06.96 ID:O5DunmIw.net] >>636 > オブジェクト変更するから、変更前の「前回オブジェクト」を持っておきたいとか、 なるほど、その発想はなかったな 私ならPersonかPersonを管理するクラスを作ってその中で履歴を管理しそうだ
659 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 23:38:40.69 ID:K+DNMsci.net] >>639 だから、あのさあ。。 他の言語で考えてみれば?そんな関数は、jsで言う、そのインスタンスのプロトタイプが持つべきで、そのインスタンスが持つべきものじゃないでしょ。 二回目だけど、それはdeepcopyではない。 どうしてもしたければ、laveでもしろ。 問題が理解出来てなさすぎるんじゃないか? >>640 Personを管理するクラスを作ったなら、そいつが持つのは一体何なんだ? Personじゃないの? 「Person」と、「Personのコピー」と、「PersonとPersonのコピーを管理するクラス」って無駄すぎるだろ。 どう考えてもPersonを正しくコピー出来るべきで、Personのインスタンス同士を中身を使って比較出来るべきじゃないの?
660 名前:デフォルトの名無しさん mailto:sage [2016/06/13(月) 23:45:19.16 ID:O5DunmIw.net] >>641 JSONでもdeep copy出来てなかったと思うのだが 否定ばかりであなたの考える最善が何も出てこないな
661 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 00:47:25.44 ID:DODkZCvX.net] JavaScriptで deep copy に最適解は存在しないので自分のポリシーに照らし合わせて一番無理のない実装を考える 例えば、次のオブジェクトの deep copy が難しい var obj = { date: new Date, regexp: /test/g, img: new Image(100, 100), window: window, document: document.implementation.createHTMLDocument('sample'), elementInIframe: document.querySelector('iframe').contentDocument.getElementById('hoge'), fn: (function (i) { return function fn () { return i++; }; }(0)) }; date, regexp は getPrototypeOf で [[Prototype]] を確認すれば実装可能 img, document, elementInIframe は cloneNode で可能 window は new Window する仕組みがないと難しい fn は Function#toString を取るだけではスコープの問題を解決不可能なので無理 この調子で一つ一つ対処していったらキリがないのでどこかで妥協するのが普通 ちなみに、deep copyでJSONを持ち出すのは妥協の結果であり、他を圧倒するほどのメリットはない(そもそも、シリアライズする意味がない) それぞれの妥協解を開示して意見を募るぐらいが妥当ではないかね
662 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 02:01:10.19 ID:9x/TacpJ.net] >>642 最善は、オブジェクトはオブジェクトとして、関数をもたず、単なるデータの塊として、関数とは別に定義して、 stringify/parseで文字列と相互に変換できる、だよ。 ネットワークを経てrpc的なもので関数呼び合うにも便利だし。 値の持ち主が関数を持つのは好きじゃない。 >>643 圧倒するほどのメリットと言えば、それこそAPIやら、socket.ioを経ても素直に透過な所じゃないかな。
663 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 02:03:53.91 ID:M6DJWkXG.net] >>644 日付が壊れる問題はどうすんの?
664 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 02:06:47.27 ID:M6DJWkXG.net] あれ?もしかしてまだ日付が壊れる問題の詳細でてなかったの? 日付らしき文字があったからもう情報出てると思ってたw まあぐぐればすぐに分かるよね?って話。 JavaScriptのDeepCopyでJSON.parse/stringifyを使ってはいけない qiita.com/seihmd/items/74fa9792d05278a2e898
665 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 02:11:20.97 ID:M6DJWkXG.net] >>644 > 最善は、オブジェクトはオブジェクトとして、関数をもたず、単なるデータの塊として、関数とは別に定義して、 > stringify/parseで文字列と相互に変換できる、だよ。 理由がないよね。 > ネットワークを経てrpc的なもので関数呼び合うにも便利だし。 今はDeep Copyの話をしている。 シリアライズの話なら別でやれ
666 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 02:24:34.32 ID:TbEnZJwB.net] >>645-646 なんでこういう事いう奴のJSON.parse/stringifyには第二引数がないんだろう?w
667 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 02:31:07.43 ID:M6DJWkXG.net] JSON.parse/stringifyには第二引数で頑張ればできるという誤解が 広まらないように先に言っておくと、これはNumber、String、Booleanにしか 対応できません。
668 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 04:26:35.95 ID:TbEnZJwB.net] >>649 嘘吐くなよ試しちまったじゃねぇかw parseに渡すreviverは文字列を受け取って問題なくオブジェクトを返せるし stringifyに渡すreplacerはオブジェクトを受け取って任意の文字列に変換出来る 別にコピーのためだけに局所的に使うならreplacerは正しいjsonを吐く必要もないしな 復元のための情報山盛りにして吐き出せばいい Dateとundefinedを試してコピー出来たのは確認した Functionとクロージャはスコープの問題があるのでシャローコピーにせざるを得ないが 同一スコープ内でstringify/parseをするならreviverでオリジナルから参照をコピーするのは簡単だ ただまあここまでやるのはシリアライザとデシリアライザを自前で実装するのと変わらんからオブジェクトを直接弄った方が早いなw ところでディープコピーってjQueryからextendメソッドをパクって来るんじゃダメなんか? 循環参照で死ぬので他のライブラリのでもいいがディープコピーを実現しようとしてるライブラリは少なくないと思うんだが
669 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 09:05:34.57 ID:BcKyLCvc.net] >>634 「js button click event」で検索!
670 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 09:26:05.33 ID:VOPCCsis.net] >>651 「いやです!>_<」
671 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 09:30:58.95 ID:DODkZCvX.net] >>644 > 最善は、オブジェクトはオブジェクトとして、関数をもたず、単なるデータの塊として だから、それをどうやって実装するのか、という事を聞いているのだが 「データの塊」とはJSONにあるような「プロパティの塊」の事か? function Person (name) { this.name = String(name); } var obj = {name1: new Person('Ken'), name2: {name: 'Ken'}}; console.log(JSON.stringify(obj)); // "{"name1":{"name":"Ken"},"name2":{"name":"Ken"}}" 結局、JSONの問題点は克服できてないのだが あなたの頭の中がJSONに最適化されているからJSONにそぐわないコードを意識的に追い出しているに過ぎない - 関数が消されるが、使わないので問題ない - undefined は消されるが、undefined をプロパティ値に持たないので問題ない - new Date は String 型に変換されるが、後で new Date し直すので問題ない - new Arrayを除く全てのオブジェクトは new Object に変換されるが、オブジェクトおを「プロパティの塊」としかみないので問題ない - new Date(2016, 5, 14, 9, 0, 0) と "2016-06-14T00:00:00.000Z" が同値を認識されるが、データの塊としか見ないので問題ない - new function Person (name) { this.name = name; }('Ken') と {name: 'Ken'} が同値と認識されるが、オブジェクトを「プロパティの塊」としか見ないので問題ない > 圧倒するほどのメリットと言えば、それこそAPIやら、socket.ioを経ても素直に透過な所じゃないかな。 JSONはシリアライズ不可能なオブジェクトを扱えないデメリットがある 「あなたは」シリアライズ不可能なオブジェクトを使わないからJSONが最適解だが、「私は」シリアライズ不可能なオブジェクトを扱うので最適解が「シリアライズ不可能なオブジェクトを社ローコピーする」になっている トレードオフの関係にあることは間違いない
672 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 09:41:30.57 ID:DODkZCvX.net] >>643 の obj を JSON.stringify(obj); すると SyntaxError になるな
673 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 10:11:55.55 ID:dYSnVaKQ.net] >>653 最適解が「シャローコピー」となる、その主語はなに? 何に関して議論してるの?
674 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 10:29:28.31 ID:ScASA3Ww.net] 別にJSON使ってもいいと思うけど、 別の手としてはMessageChannel使えば非同期で循環参照も扱える まあJSONも少し手を加えれば循環参照を扱えるが 昔作ったこんな感じで ideone.com/Zxp7kN 昔関数も扱えないかと考えたことがある まあちょっとコピーとは感じが違うが、NodeとブラウザでWSを使いオブジェクトを共有しようと思っていた。 その時はオブジェクト情報を送るのではなく影となるProxyを使い、 操作を原本に問い合わせることでだいたい可能という判断になった。 原本に与える影響を最小限にして、あたかもでディープコピーされたかのように振る舞うのも まあ巧みなProxyとレシーバーを守るメソッド定義に気をつけていれば可能な範疇だろう
675 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 11:59:42.69 ID:9x/TacpJ.net] >>653 頭おかしいのかな。 そうだと言ってるんだよ。 データと操作と、操作のためのオブジェクトは別個に考えるべきだと。 最適解として、シリアライズ不可能な物はシャローコピーする、は、 お前の運用に対する無難な妥協点であって、ディープコピーじゃないよ。 だからlave使えって。
676 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 12:02:10.51 ID:9x/TacpJ.net] >>654 toJSON実装しとけ。
677 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 12:50:00.83 ID:DODkZCvX.net] >>655 シリアライズ不可能なオブジェクト >>657 「あなたの考えるdeep copyかどうか」はどうでもいいんだがな 「あなたの考えるあなたの為のdeep copy」が私にとっては使えないし、逆もしかりというだけなんだが で、「あなたの考えるdeep copy」と「私の考えるdeep copy」の仕様が違うだけ laveとは何のことだ? >>658 toJSONとは?
678 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 12:51:12.47 ID:DODkZCvX.net] 追記 「ディープコピーじゃないよ」といわれてもあなたの中ではそうなんだろう、としか言いようがない
679 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 13:11:10.09 ID:dYSnVaKQ.net] >>659 > シリアライズ不可能なオブジェクト それ、そもそも問題設定がおかしくないか? もともとはオブジェクトをコピーするときの話で、その目的・実現方法による分類として シャローコピーとディープコピーがある。 シリアライズ不可能なオブジェクトでもシャローコピーで良い場合もあれば悪い場合もある。 それは目的によって異なるというだけのこと。
680 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 13:20:14.73 ID:dYSnVaKQ.net] >>689 からも話が続いてるとして、 > 一口にdeep copyといってもいろいろ問題があるわけで「この問題にあなたはどう考えているのか?」 > この問題は個々がdeep copyする状況によって解決策が変わるだろうからあなたの考えがな聞きたかった つまり、ディープコピーしたいんだが、ある項目についてはそれが難しいという話でしょ? で、その問題解決の最適解がシャローコピー? >>636 の > オブジェクト変更するから、変更前の「前回オブジェクト」を持っておきたいとか、 > 保存ボタン押すときに、保存の必要性あるか確認したいから、オブジェクトと退避オブジェクトを比較したい、その退避オブジェクトを作るとか 目的でディープコピーをしたいのだという人と、根本的に議論がかみ合ってない。
681 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 13:22:09.03 ID:9x/TacpJ.net] >>659 deepcopyの定義から考えような。勝手キーワードじゃないよ。 https://en.m.wikipedia.org/wiki/Object_copying#Deep_copy laveはこれ。 https://github.com/jed/lave/blob/master/README.md toJSON https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify >>660 お前の中でしか違わないよ。
682 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 16:09:36.89 ID:9x/TacpJ.net] まぁ、===で比較したいから、インスタンスは唯一の存在であってほしいから、これは「俺のdeep copy」とか言われても困るわな。 絶対地雷踏み抜くわ。 同名のtaroオブジェクトとかで苦笑いしておくべきだったか。
683 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 17:54:57.29 ID:DODkZCvX.net] >>663 あなたの主張はわかった
684 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 18:07:30.48 ID:dYSnVaKQ.net] あなたの主張はわかった。 => でもそれは間違ってる => 私が間違っていた => あなたも正しいが、私の主張も正しい のどれだろうか。
685 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 18:47:33.56 ID:9x/TacpJ.net] >>665 無知を省みて自分の至らぬ所を認め、その上で正しい知識を入れ直さないと、 技術者として致命的な場面がやってくるよ。 匿名で出来る間にやっておけばいかがかな。
686 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 19:35:30.53 ID:TG3hSyiU.net] 一般論からは、複製するオブジェクトを利用している文脈に固有のデータは 複製されない方がよいだろう(一時的な管理データなど よって、何を複製すべきかは複製した結果を利用する文脈に依存する 元と同じ文脈で利用する場合でも、すべてのデータを複製した方が いいとは限らない( id みたいに重複すると困るものなど
687 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 22:10:43.05 ID:VJ/4c5wE.net] ディープコピーは滅多に使わないな マップした結果が偶々ディープコピーと同じ結果になる事はあるけど 転送はJsonXmlバイナリのどれかのシリアライズだし
688 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 23:14:40.87 ID:9x/TacpJ.net] 一般論としては、ってのがよくわからんが、そんなものをデータに持ち込むからじゃないの?
689 名前:デフォルトの名無しさん mailto:sage [2016/06/14(火) 23:28:10.46 ID:M6DJWkXG.net] ディープコピーとシリアライズは別の機能。 ディープコピーにシリアライズ用の関数を使うのは間違い。 それだけの話だろ
690 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 00:12:34.59 ID:cIXZs8w1.net] >>671 そりゃおっしゃる通り。 一番元々の要件に対して、「手軽で早い」解決策。 そこから、変なものをdeepcopyだと寝言言う奴があらわれてこうなっただけ。 cloneとequalsを定義すべきだと思うよ。「正しい実装」では。
691 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 00:19:47.28 ID:wTcNi+2O.net] >>672 もともとの要件? もともとの要件は、ディープコピーなんだが?w ディープコピーにシリアライズ用の関数を使うのは間違いって JSONつかってやるコードを持ち出してきた >>661 をぎったんぎったんに叩いてやれよw ↓しっかり思い出せやw 608 自分:デフォルトの名無しさん[sage] 投稿日:2016/06/12(日) 23:34:06.35 ID:xguVhByI [2/2] shallowコピーの場合はconcatでいいよね。 最初は?ってなるけど、知ってしまえば簡単に覚えられるし。 なんらかのdeepコピーの場合はライブラリ使うしか無いかな? 611 返信:デフォルトの名無しさん[sage] 投稿日:2016/06/12(日) 23:57:34.48 ID:hCgFiHr7 [7/7] >>608 JSON.parse(JSON.stringify(obj)) が、一番手軽で早い。
692 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 01:25:24.86 ID:Iz/1ukPU.net] ディープコピーといっても様々じゃない? 構造下のオブジェクトは再作成することになるが、 関数に限ってはクロージャの面からも参照コピーした方がいい。 しかしそうなると関数オブジェクトのプロパティの取り回しが困る。 他にも非列挙やシンボルの扱いもあるし一般的に何が正しいかなんてない。
693 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 02:03:52.98 ID:wTcNi+2O.net] >>674 例えそうだとしても日付が壊れるとか undefinedが消えるだとかいうのは問題外
694 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 04:32:57.44 ID:Iz/1ukPU.net] そっとしてそれはギャグで言ってるのかな?
695 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 08:08:29.44 ID:SSaOcc+i.net] >>673 ディープコピー全体に対して、すべてをシリアライズで解決するのは正しいか間違いか、 って話であって、 少なくともconcat使うような配列やらなんやらでは、シリアライズで必要十分だねと。 訳わからん前提を持ち出して、あまつさえディープコピーではないものをディープコピーと言い出した奴は気が狂ってると思うけど。 だから、何度かclone/equalsの話もしてんじゃん。 お前、自分が何故叩かれたか理解してないの? >>675 そんな形で持つからだろ。
696 名前:デフォルトの名無しさん mailto:sage [2016/06/15(水) 08:56:16.37 ID:FEVYup+X.net] javascript業界は素人ばっかりだな 参照型のディープコピーの実装は大きく分けて3つ プロパティの自動マッピング、シリアライズ、明示的なコピー関数 実行効率や制約の多さはともかくとして工数的にはシリアライズを利用する方法は有力な選択肢だよ もちろんそもそも論としてディープコピーなんかそんなに使わないってのがあるけどね