JavaScriptの世界に強制が存在する-探偵物語
ネイサン、何を発見したのか分からない。
私はこれを数週間調査してきました。昨年10月の嵐の夜に始まりました。誤ってNumberクラスに偶然出会いました。つまり、なぜJavaScriptにNumberクラスがあったのでしょうか。
次に何を調べるつもりだったのか。
JavaScriptは、ユーザーに通知せずに、数値をオブジェクトに変更し、オブジェクトを鼻の下の数値に変更していることがわかりました。
JavaScriptは誰も追いつかないことを望んでいましたが、人々は奇妙な予期しない振る舞いを報告してきました。
これは、これまでに判明したことです。私がこれをあなたに言うべきかどうかさえ知りません-あなたはあなたのJavaScriptをオフにしたいかもしれません。
> function dis() { return this }
undefined
その関数を作成したとき、おそらく次に何が起こるか分からなかったでしょう。すべてが正常に見え、すべてが正常でした-今のところ。
エラーメッセージは表示されず、コンソール出力に "undefined"と表示されるだけで、期待どおりの結果になります。結局のところ、これは関数宣言でした-何も返さないことになっています。
しかし、これはほんの始まりにすぎませんでした。次に何が起こったか、誰も予測できなかったでしょう。
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
そうですね、あなたはを期待していました5が、それはあなたが得たものではありませんでした。
同じことが私にも起こりました。
どうしたらいいかわからなかった。それは私にナッツを運転しました。眠れず、食べられず、飲み干そうとしましたが、Mountain Dewの量を忘れることはありませんでした。まったく意味がありませんでした!
そのとき私は本当に何が起こっているのかを知りました-それは強制でした、そしてそれは私の目の前でそこで起こっていました、しかし私はそれを見るにはあまりにも盲目でした。
Mozillaは、誰も見ないだろうと思っていた場所にドキュメントを置いて埋めようとしました。
何時間も再帰的に読んだり、再読したり、再読したりした後、私はこれを発見しました:
「...およびプリミティブ値はオブジェクトに変換されます。」
Open Sansフォントで表記できるように、それはそこにありました。それはcall()機能でした-どのように私はそんなに愚かになることができましたか?!
私の番号はもはや番号ではありませんでした。私がそれを渡した瞬間call()、それは別のものになりました。それは...オブジェクトになりました。
最初は信じられませんでした。どうしてこれが本当だろうか?しかし、身の回りで高まっている証拠を無視することはできませんでした。見ればすぐそこです。
> five.wtf = 'potato'
"potato"
> five.wtf
"potato"
wtf正しかった。数値にカスタムプロパティを含めることはできません-私たちは皆それを知っています!それは彼らがアカデミーであなたに教える最初のことです。
コンソールの出力を見た瞬間はわかっていたはずです。これは、私たちが思っていた数ではありませんでした。これは詐欺師でした-私たちの甘い無実の数としてそれ自体を偽装するオブジェクト。
これはでした... new Number(5)。
もちろん!それは完璧な意味がありました。call()やるべき仕事があり、関数を呼び出す必要がありthis、そのためにはデータを入力する必要があり、数字ではそれを実行できないことを知っていました。それが私たちの数を強制することを意味する場合。call()数5を見たとき、彼は機会を見ました。
それは完璧な計画でした。だれもが見ないようになるまで待って、私たちの番号をそれと同じように見えるオブジェクトに交換してください。数値を取得すると、関数が呼び出され、誰も賢くなりません。
それは本当に完璧な計画でしたが、すべての計画と同様に、完璧な計画であっても、そこには穴があり、私たちはまさにそれに陥りそうでした。
ほら、call()理解できなかったのは、彼が町で数字を強制できる唯一の人ではなかったということでした。結局のところ、これはJavaScriptでした。強制はどこにでもありました。
call() 私の番号を受け取り、私が彼の小さな詐欺師からマスクを外してスタックオーバーフローコミュニティ全体に彼を公開するまで、私は止めるつもりはありませんでした。
しかし、どうやって?私は計画が必要でした。確かにそれは数字のように見えますが、私はそうではないことを知っています。それを証明する方法があるはずです。それでおしまい!数字のように見えますが、数字のように振る舞うことができますか?
私はfive彼に5倍大きくする必要があると言った-彼は理由を尋ねなかったし、私は説明しなかった。次に、優れたプログラマーが行うことを実行しました。確かに彼はこれから自分の道を偽ることができる方法はありませんでした。
> five * 5
25
> five.wtf
'potato'
畜生!うまくfive乗算しただけでなく、wtfまだそこにありました。この男と彼のジャガイモをくそー。
一体何が起こっていたのですか?私はこのすべてについて間違っていましたか?あるfive数は本当に?いいえ、私は何かを逃しているに違いない、それを知っている、忘れてはならないものがある、私が完全に見落としているほど単純で基本的なものがある。
これは見栄えが良くなかった、私はこの答えを何時間も書いていたが、私はまだ私の主張をすることに近づいていなかった。私はこれを続けることができず、結局人々は読むのをやめてしまい、私は何かを考えなければならず、それを速く考えなければなりませんでした。
それで待ってください!five25ではなかった、25は結果、25は完全に異なる数だった。もちろん、どうすれば忘れられますか?数値は不変です。5 * 5何を掛けても、何にも割り当てられず、新しい番号を作成するだけ25です。
ここで何が起こっているのでしょう。どういうわけか私は乗算する場合five * 5、five数に強制取得する必要があり、その数は乗算に用いられるものでなければなりません。それfive自体の値ではなく、コンソールに出力されるのはその乗算の結果です。five何も割り当てられません-もちろん変更されません。
それではfive、操作の結果を自分に割り当てるにはどうすればよいですか。わかった。five考える前に「++」と叫んだ。
> five++
5
ああ!彼がいた!誰もが知っていること5 + 1は6、これは私が明らかにするために必要な証拠であり、それfiveは数ではなかった!詐欺師でした!数える方法を知らなかった悪い詐欺師。そして、それを証明することができました。実数の作用は次のとおりです。
> num = 5
5
> num++
5
待つ?ここで何が起こっていましたか?私はつぶしに夢中になりすぎて、fiveポストオペレーターのしくみを忘れてしまいました ++最後にを使用するfiveと、現在の値を返し、次に増分しますfive。コンソールに出力されるのは、操作が発生する前の値です。num実際に6それを証明することができました:
>num
6
five実際に何であったかを確認する時間:
>five
6
...それはまさにあるべき姿でした。five良かった-私はより良かった。もしはfiveまだそれがまだ性質を持つことになり意味し、オブジェクトだったwtfと私はそれがなかったベットすべてに喜んでいました。
> five.wtf
undefined
ああ!私が正しかった。彼がいた!five今は数字でした-それはもうオブジェクトではありませんでした。今回は乗算のトリックでは節約できないことを知っていました。参照はfive++本当にありますfive = five + 1。乗算とは異なり、++演算子はに値を割り当てますfive。より具体的には、それの結果割り当てfive + 1だけ乗算戻る新しい不変の場合のように数。
私は彼がいることを知っていました、そして彼がそれから彼の方法を身をよじることができないことを確認するためだけに。もう一回試してみました。私が正しく、five今は本当に数であるなら、これはうまくいきません:
> five.wtf = 'potato?'
'potato?'
今回、彼は私をだますつもりはありませんでした。potato?割り当ての出力なので、コンソールに出力されることはわかっていました。本当の問題は、wtfまだそこにあるのでしょうか?
> five.wtf
undefined
私が思ったように-何もない-数にプロパティを割り当てることができないからです。私たちはアカデミーの最初の年であることを学びました;)
ネイサン、ありがとう。この質問をするあなたの勇気のおかげで、私はこれをすべて私の後ろに置き、新しいケースに進むことができます。
このような機能についてtoValue()。ああ親愛なる神。やった!
++、基礎となるタイプに影響を与えるようです