인터넷에서 온 이미지의 JavaScript 괴벽
12236 단어 javascript
사진 속 사람은 Brendan Eich, Java Script의 창립자, 모질라 프로젝트의 공동 창시자이다.
설령 어떤 예가 언어 자체와 진정한 관계가 없다 하더라도 나는 그것이 매우 재미있고 간단명료하게 분해할 수 있다고 생각한다. 이것은 고전적인'엄격한 언어'(프로그래밍 배경만 있는 사람)에게는 큰 의미가 없다는 것을 감안하면.
붕괴
보어 섹션부터 시작합니다.
부동점 산술
> 9999999999999999
< 10000000000000000
> 0.5+0.1==0.6
< true
> 0.1+0.2==0.3
< false
이것은 결코 이상하지 않다. 이것은 이미 오래된 개념이다.물론 JavaScript의 특성과는 무관합니다.여기서 설명하기보다 this great'explainlikeimfive'사이트에 링크된 것만 남겨서 부동점 수학을 해석하는 데 사용합니다.숫자 아니면 숫자.
> typeof NaN
< "number"
'난'은 도대체 뭐야?사실상 이것은 특정한 값의 표시로 수치 유형의 제한에 표시할 수 없다(실제로 유일한 JS 수치 원어는 float
.NaN은 IEEE 754 부동 소수점 표준에 도입되었습니다.그래서 이것은 단지 컴퓨터가 이 특정 환경에서 계산할 수 없는 숫자일 뿐이다.
유형 변환
JavaScript는 동적 형식 언어로 침묵 (은식) 형식의 강제에 익숙하지 않은 사람들에게 가장 얄미운'왜 이러니'디버깅 세션을 초래할 수 있다.
단순 섹션: 엄격함
===
> true === 1
< false
엄격하게 두 값을 비교하다.비교를 진행하기 전에 두 값 모두 암시적으로 다른 값으로 변환되지 않습니다.값의 유형이 다르면 값이 같지 않다고 간주됩니다.부울 변수는 1이 아니라 숫자입니다.다른 한편, 이것은 다음과 같다.
> true == 1
< true
이것은 암시적 유형 강제의 예이다.연산자를 다른 유형의 값에 적용하면 암시적 유형 강제가 발생합니다: 2+'2'
, 'true'+false
, 35.5+new RegExp('de*v\.to')
또는 if (value) {
같은 특정 유형으로 예상되는 특정 컨텍스트에 값을 넣습니다.JavaScript 형식 변환은 가장 간단한 부분이 아니기 때문에 저는 Alexey Samoshkin의 this great article과 this little MDN doc의 등식 비교에 관한 글을 더 읽을 것을 건의합니다.그리고 이것equality comparison cheatsheet이 도움이 될 것 같습니다.
어쨌든 우리 화면으로 돌아가자.
> [] + []
< ""
JS에는 두 가지 유형의 변수가 있습니다. 대상과 원어입니다. 원어는 boolean
, number
, string
, boolean
, undefined
, null
, symbol
및 boolean
입니다.다른 모든 것은 함수와 그룹을 포함한 대상이다.스텔스 변환을 호출하는 연산자를 포함하는 표현식을 실행하면 전체 표현식은 세 가지 기본 유형 중 하나로 변환됩니다.
대상:
true
상황에서 모든 비원어 값은 string
로 강제됩니다.number
및PreferredType
의 경우 다음 내부 작업ToPrimitive(input, PreferredType)을 실행 중이며 옵션number
은 string
또는input.valueOf()
이다.그러면 다음 알고리즘이 실행됩니다.input.toString()
.결과가 기원이면 반환됩니다.PreferredType
은string
이면 2와 3을 교환합니다.위의 실제 JavaScript에서의 위조 실현을 보고 볼 수 있다. 게다가 볼 변환(처음에 앞에서 언급한 문장을 통해 이루어졌다courtesy of Alexey Samoshkin.
function ToPrimitive(input, preferredType){
switch (preferredType){
case Boolean:
return true;
break;
case Number:
return toNumber(input);
break;
case String:
return toString(input);
break
default:
return toNumber(input);
}
function isPrimitive(value){
return value !== Object(value);
}
function toString(){
if (isPrimitive(input.toString())) return input.toString();
if (isPrimitive(input.valueOf())) return input.valueOf();
throw new TypeError();
}
function toNumber(){
if (isPrimitive(input.valueOf())) return input.valueOf();
if (isPrimitive(input.toString())) return input.toString();
throw new TypeError();
}
}
따라서 당일 종료 시 원본[] + [] == ""
은 다음과 같이 해석됩니다.ToPrimitive([]) + ToPrimitive([])
두 그룹 모두 빈 문자열을 되돌려줍니다. 결과는 toString([])
입니다.최종 결과는 두 개의 빈 문자열의 직렬입니다.이제 다음을 수행합니다.
> [] + {}
< "[object Object]"
String({})
로 인해[object Object]
, 결과는""
과"[object Object]"
의 간단한 직렬이다.간단해.지금 이게 도대체 어떻게 된 일입니까?> {} + []
< 0
사실이 증명하듯이 JavaScript는 첫 번째{}
를 코드 블록으로 설명합니다!해석 입력을 시작할 때부터 끝낼 때까지 {
을 블록의 시작으로 간주하고 닫습니다 }
.따라서 우리의 위조 실현을 사용하면 앞의 예는 다음과 같이 평가될 것이다.ToPrimitive(+[])
..이것은 0입니다.+
는 조작수를 숫자로 바꾸는 데 사용되는 일원 접두사 연산자이다.느슨함
==
과 바이너리+
연산자는 항상 기본값preferredType
을 터치하고 기본값은 숫자로 변환합니다(문자열을 반환한 날짜는 제외).이것은 true+true+true===3
과true==1
를 설명한다.따라서 예상한 대로 true===1
되돌아오기 false
표현식 왼쪽에 연산자가 없기 때문에 ===
은밀한 형식의 강제를 촉발하지 않습니다.[]==0
과 마찬가지로 대체적으로 Number([]) == 0
에 해당한다.모든 일은 재미있는 예를 가져다 줄 것이다. 예를 들어 우리가 여기에 있는 예:
> (!+[]+[]+![]).length
< 9
그것을 분해하고,아주 간단해요.
마지막으로 (가장 중요한 것은 솔직히 말하면):
수학max()<수학.min()?
> Math.max()
< -Infinity
> Math.min()
< Infinity
일부 파라미터가 필요한 함수가 의외의 결과를 되돌려주는 측면에서 볼 때, 이것은 비교적 작은 언어 결함으로 간주될 수 있다.그러나 사실 이 뒤에는 실제 수학 지식이 있다.
이 가능하다, ~할 수 있다,...
Math.max = function () {
let temp = -Infinity;
for ( let i = 0; i < arguments.length; i++ ) {
let num = Number(arguments[i]);
if ( num > temp ) {
temp = num;
}
}
return Number(temp);
}
현재, 매개 변수를 전달하지 않았을 때 되돌아오는 것은 의미가 있다.Math.max()
은-Infinity
의identity element입니다.바이너리 작업의 표지 요소는 상기 작업을 두 요소에 적용한 후 다른 요소가 변하지 않는 요소이다.그래서 0은 덧셈의 항등식이고 1은 곱셈의 항등식이다.
-Infinity
및 Math.max()
은 항상 x+0
입니다.x*1
및 x
에서 -Infinity
은 항상 최대 수입니다.찰리 하비의 절대gorgeous article는 이 화제를 깊이 있게 탐구했다.
한 마디로 하면 스텔스 유형의 강제는 매우 중요한 개념이므로 당신은 시종 명심해야 합니다.느슨한 평등을 피하다.당신이 무엇을 비교하고 있는지 생각해 보세요. 가능한 한 현식 변환을 사용하세요.위의 내용이 두렵다면 TypeScript로 전환하는 것을 고려하십시오.)
더 많은 "wtf"자바스크립트를 보고 싶다면, wtfjs 라는 훌륭한 자원이 있고,
x
매뉴얼로도 제공할 수 있다.
Reference
이 문제에 관하여(인터넷에서 온 이미지의 JavaScript 괴벽), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mkrl/javascript-quirks-in-one-image-from-the-internet-52m7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)