X



+ JavaScript の質問用スレッド vol.134 +
■ このスレッドは過去ログ倉庫に格納されています
0001Name_Not_Found
垢版 |
2018/06/04(月) 16:22:58.13ID:aMAv4I5k
JavaScript を自ら学ぶ人のための質問スレッドです。
次スレは>>950が(本スレで改善案があれば考慮して)立ててください

■規則/推奨ルール
・メール欄を空欄にし、名前にレス番を入れることを強く推奨(なりすまし防止)
・質問内容は具体的に。言葉だけでなく、出来る限り再現性を確認したサンプルコードの掲示。
・質問テンプレートの利用推奨。
・質問への「答え」だけでなく「意見」を出しても良い。

■禁止行為
・丸投げ質問
・迷惑スクリプトの質問
・オレオレ用語の使用(一般的な用語を使用する事)
・煽り、批判等の他人を不快にさせる行為(批判の代わりに「AよりBが良い」のような代案を出す事)

■質問テンプレート
【環境】OS, ブラウザをバージョンと共に記入してください。
【条件】期待する回答の条件を書いてください。
【何をしたのか】何をしたら問題の現象が発生するのか。再現手順を具体的に書いてください。
【エラーメッセージ】エラーメッセージがあれば正確に書き写してください。
【期待する結果】最終的にどういう結果を望んでいるのか、を書いてください。
【サンプルコード】現象を再現可能な最小限のコードを書いてください。
 1レスに収まらないならコード投稿サイトを利用してください。
 http://jsdo.it/ http://jsbin.com/ http://jsfiddle.net/ http://ideone.com/

■回答者へ
・回答には多様性があります。他人の回答を尊重してください
・動作ブラウザや環境が限られる場合は、それを明記してください
・他人の回答を批判する代わりに、自分ならこう書くという例を示してください
・質問者がJavaScriptでなければ実現できないと勘違いしてるなら、その否定としてHTMLとCSSで実装しても良い
・他人の回答を見たくないのであれば、文句をつける代わりにNGにして見えないようにしてください。文句をつける=荒らしです
0003Name_Not_Found
垢版 |
2018/06/07(木) 21:28:55.62ID:???
MySQLとMongDBならどっち?
このスレできく理由も勝手にエスパーして考慮に入れてお願いします。
0004Name_Not_Found
垢版 |
2018/06/07(木) 21:58:02.88ID:???
そんな聞き方する奴にrdbは合わないに決まってるのでmongo。
0006Name_Not_Found
垢版 |
2018/06/08(金) 00:59:57.44ID:???
>>4
「そんな」ききかたではありません!
回答者の経験と発想を最大限尊重した
自由意思にゆだねた回答を求めるとてもリスペクトフルな質問法です!!
0007Name_Not_Found
垢版 |
2018/06/08(金) 01:24:05.63ID:???
テンプレ滅茶苦茶になった挙げ句ついにほぼカットされたか
0008Name_Not_Found
垢版 |
2018/06/08(金) 06:39:51.84ID:???
とりあえず巻き上げに関して正しておく
宣言された変数が属するスコープ内全域に浸透するのは当たり前
JSの巻き上げとは、宣言ではなく初期化の話
varならundefinedで、関数宣言なら関数値で初期化されることを巻き上げと言う

勿論アロー関数は巻き上げされたりはしない
ただアロー関数には変数宣言文中に定義することで
その変数名の名前がつくという特殊挙動がある
0009Name_Not_Found
垢版 |
2018/06/08(金) 07:02:20.40ID:G7whztLr
>>6
レスを最大限分析された的確な答えだと気づくべき
0010Name_Not_Found
垢版 |
2018/06/08(金) 08:09:56.78ID:???
>>4
あのさー、お前がね、いちいち用語の定義をする必要はないんだわ
世間一般に知られたことは、世間一般的な用語の定義があるんだから
それを引用して書けばいいだけ


https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/var
> この動作は、変数の宣言が関数やグローバルのコードの先頭に移動したように見えるため、
> "巻き上げ (hoisting)" と呼ばれます。

変数の "宣言" が移動する。それが巻き上げ
001110
垢版 |
2018/06/08(金) 08:10:27.64ID:???
>>4じゃなくて>>8宛ね
0012Name_Not_Found
垢版 |
2018/06/08(金) 08:25:10.85ID:???
宣言とundefinedによる初期化は別々なのか?

var testvar; console.log(testvar); とだけ書くとundefinedが出力される

・元から先頭にあるのだから巻き上げは行われない、宣言が常にundefinedでの初期化を内包する
・元から先頭にあっても巻き上げが実施される、巻き上げにより宣言とundefinedでの初期化が行われる

どっちなのか判別が付かん
0013Name_Not_Found
垢版 |
2018/06/08(金) 10:44:46.46ID:???
スッゲ曖昧な知識だが。
function命令は命令なので、ちょっと特殊で、最初に読み込まれる。だから巻き上げが出来る
変数は最初に名前だけ収集解析だけされて、値の入ってない変数のリストだけが作られ構造化される。
だったような。

アロー関数がなぜ変数にいれているのに、巻き上げ?がおこるのかはしらない。
0014Name_Not_Found
垢版 |
2018/06/08(金) 11:01:32.95ID:???
概念についてあーだこーだ言われても確認できるコードがないとわからん
0015Name_Not_Found
垢版 |
2018/06/08(金) 11:18:35.65ID:???
これは知識不足というか、経験的に浅いと言った方がいいのか
巻き上げというものがあるんだ、そうなんだね!
ぐらいにしか考えてなさそう

なんで巻き上げという機能を実装したのかまで
考えられてない。C言語をしらないからか、
いや昔のC言語と言ったほうがいいのか
C言語に対するJavaの特徴といったほうが良いのか

なんでこうなってるかの、基本がないのは
時代の流れの方が理由大きいのかねぇ
0016Name_Not_Found
垢版 |
2018/06/08(金) 11:25:46.46ID:???
今のC言語はちょっと違うが、昔のC言語っていうのは、
関数は宣言してからじゃないと使えなくて、
変数の宣言は関数の頭の方に書くしかなかったんだよ

void foo() {
 int i; // OK
 int j; // OK
 bar(); // NG 先に宣言されてない = この時点では知らないので使えない
 int k; // NG 関数の頭じゃないからここで宣言できない
}

foo(); // OK 先に宣言されてるから使える

void bar() {
 return 0;
}

それを他の言語は、先に宣言されて無くても
スコープ内で宣言されていればOKにしたほうが
いいんじゃねという考えで改良したんだよ。
Javaはそれを特徴の一つにもしていた
0017Name_Not_Found
垢版 |
2018/06/08(金) 11:26:59.18ID:???
ちなみに当時はコンパイラの時代で、主にコンパイルする時点で
先に宣言されて無くてもOKという機能だった
0018Name_Not_Found
垢版 |
2018/06/08(金) 11:34:23.93ID:???
なんで先に宣言されてないといけないのかというと
関数に関しては、ファイルの頭からコンパイルするときに、
いきなり知らない名前がでてきたらどう処理したら良いかわからんし

変数というのは、関数内で一時的に(スタックに)メモリを確保して
関数が終わったら解放しなきゃいけないから。
頭にまとまってりゃ関数の最初でその処理をやって
関数終了に解放するだけで簡単

主にコンパイラの実装が簡単だからそうなってたんだよ。

これはインタプリタのJavaScriptでも同じ
だが、先に宣言されて無くてもOKにしたほうが便利だろう?

だから、先に宣言されているかのように
内部的に順番を入れ替えるのが、巻き上げの機能の本質
0020Name_Not_Found
垢版 |
2018/06/08(金) 11:39:23.25ID:???
あとC言語はみ初期化の変数は中になにが入っているか不定
>>16のi,j変数はなにが入っているか決まってない
その時にメモリ(スタック)に入ってるゴミデータになる

実行速度重視のC言語ではそれもやむなしだったが、
決まってない値がなにか入っているのは分かりづらいバグの原因になるので
これが他の多くの言語では、0やNULLや未初期化を表す値になることを
保証している。それがJavaScriptではundefined

宣言したときに、undefinedに初期化するのではなく
初期化されてない変数は、undefinedになると考えたほうが良い
0021Name_Not_Found
垢版 |
2018/06/08(金) 11:49:27.70ID:???
チューリングマシンの構造によるものだときいたことがるようないような。
チューリングマシンだと最初に命令をよみこんでおかないとだめだとかなんとか。
0022Name_Not_Found
垢版 |
2018/06/08(金) 11:50:26.31ID:???
ここまで言えばわかったと思うが、
JavaScriptでは宣言前でも関数や変数を使えるようにするために

var i = 1 の var i の部分に相当する宣言と、function hoge() {} の宣言の
二種類の宣言が内部的に頭の方に集められる。そういう機能でしかない。

アロー関数( 例 (param) => value) は、function hoge() {} という形ではなく
名前がないため、後で宣言したアロー関数を宣言前に呼び出すなんてことは
ありえないので上の方に集める必要はない

だが var f = (param) => value と書いた場合の、変数fに関しては
その宣言である var f の部分だけが、その他の変数と同じように
関数の頭の方に集められる(アロー関数が集められるわけではない)
0023Name_Not_Found
垢版 |
2018/06/08(金) 12:00:31.41ID:???
もっと簡単に言えば、

関数は先に宣言されて無くても使えるようしたい
変数はスタックからのメモリの確保と解放を楽にしたい

という異なる二つの目的を叶えるために
巻き上げという名前で表現されるような
処理が行われるということ

ただ変数の方は、内部的にメモリを確保すればいいだけの話なんだから
宣言前に使えなくてもいいと思うんだが
内部的に関数の頭にまとめてメモリ確保するという実装が
仕様になってしまった感じがするな。
0025Name_Not_Found
垢版 |
2018/06/08(金) 12:40:19.30ID:???
>>20
それは違うな。
JSでは未初期化の変数にアクセスすると例外になる仕様がきちんとある。
letやconstで宣言された変数は実行がその文に達するまでは未初期化の状態になる
その未初期化の区間がTDZと言われる。
未初期化と未宣言とundefinedで初期化済は皆違う。
0026Name_Not_Found
垢版 |
2018/06/08(金) 12:46:08.72ID:???
>>22
あと、アロー関数は名前がある。
var f = ( ) => { }
のように変数宣言と一緒にアロー関数が定義される場合は
特別に解釈されてf.nameがきちんと"f"になる。
0027Name_Not_Found
垢版 |
2018/06/08(金) 12:46:32.11ID:???
バカものどもがホイスト嫌ったせいでTDZなんていう化け物を産み出してしまった
0028Name_Not_Found
垢版 |
2018/06/08(金) 12:50:47.50ID:???
>>26
それ最初はchromeの独自実装だったよね?
今は仕様化されたの?
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況