JavaScript 세계에는 강요가 있습니다-형사 이야기
나단, 당신은 당신이 무엇을 발견했는지 전혀 모른다.
나는 지금 몇 주 동안 이것을 조사해 왔습니다. 지난 10 월 폭풍이 치는 밤에 시작되었습니다. 실수로 Number수업을 우연히 발견했습니다. 왜 전 세계에 JavaScript가 Number수업을 받았습니까?
다음에 찾을 내용에 대해서는 준비하지 않았습니다.
말하지 않고 JavaScript는 숫자를 객체로, 객체를 코 바로 아래의 숫자로 변경 한 것으로 나타났습니다.
JavaScript는 아무도 붙잡기를 바라지 않았지만 사람들은 예상치 못한 이상한 행동을보고했으며 이제는 당신과 당신의 질문 덕분 에이 일을 크게 열어야한다는 증거가 있습니다.
이것이 우리가 지금까지 찾은 것입니다. 내가 당신에게 이것을 말해야하는지 모르겠습니다. JavaScript를 끄고 싶을 수도 있습니다.
> function dis() { return this }
undefined
이 기능을 만들었을 때 다음에 어떤 일이 일어날 지 전혀 몰랐을 것입니다. 모든 것이 잘 보였고 모든 것이 잘되었습니다.
오류 메시지가없고 콘솔 출력에서 "정의되지 않음"이라는 단어 만 예상됩니다. 결국, 이것은 함수 선언이었습니다-아무것도 반환하지 않아야합니다.
그러나 이것은 시작에 불과했습니다. 다음에 일어난 일은 아무도 예측할 수 없었습니다.
> five = dis.call(5)
Number {[[PrimitiveValue]]: 5}
그래, 당신은 알고 5있었지만, 그것은 당신이 얻은 것이 아닙니다. 다른 것이 있습니다.
나에게도 같은 일이 일어났다.
무엇을 만들어야할지 몰랐습니다. 그것은 나를 미치게했다. 나는 잠을 잘 수 없었고, 먹을 수 없었고, 그것을 마시려고했지만 산 이슬은 나를 잊지 않을 것입니다. 이해가되지 않았습니다!
그때 내가 실제로 무슨 일이 일어나고 있는지 알았을 때-그것은 강제력이었고, 그것은 내 눈앞에서 일어나고 있었지만 그것을 볼 수는 너무 멀었습니다.
모질라는 아무도 문서를 보지 않을 것이라는 것을 알고있는 곳에 두어 매장을 시도했다 .
몇 시간을 반복해서 읽고 다시 읽고 다시 읽은 후에 나는 이것을 발견했다.
"... 및 프리미티브 값이 객체로 변환됩니다."
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(). 오 세상에 누!
++을 미치지 않지만 기본 유형에 영향을주는 것 같습니다.