정의되지 않음을 덮어 쓰지 않는다고 가정하는 것이 JavaScript에서 실제로 얼마나 위험한가요?


87

때마다 사람에 대해 테스트를 언급 undefined, 그것의 뾰족한 밖으로undefined 있도록 키워드 아닌 이 설정 될 수"hello" 있도록, 당신이 사용해야하는 typeof x == "undefined" 대신. 이것은 나에게 우스꽝스러운 것 같습니다. 아무도 그렇게하지 않을 것이고, 만약 그렇게했다면 그들이 작성한 코드를 절대 사용하지 않을 충분한 이유가 될 것입니다. 맞죠?

내가 발견 한 예를 실수로 설정 사람의 undefined에를 null,이는 그 가정 피하기위한 이유로 주어진 undefined덮어 쓰지 않습니다. 그러나 그들이 그렇게했다면 버그가 발견되지 않았을 것이고, 그것이 얼마나 더 나은지 알 수 없습니다.

C ++에서 모든 사람은라고 말하는 것이 합법적이라는 것을 잘 알고 #define true false있지만 아무도 피하고 대신 true사용 하도록 조언 0 == 0하지 않습니다. 당신은 그 누구도 그렇게 할만큼 큰 멍청이가되지 않을 것이라고 가정하고 그들이 그렇게한다면 그들의 코드를 다시는 신뢰하지 마십시오.

이것이 다른 누군가가 undefined(의도적으로) 할당 된 누군가를 물려서 당신의 코드를 깨뜨린 적이 있습니까? 아니면 이것은 가상의 위협에 가깝습니까? 나는 내 코드를 조금 더 읽기 쉽게 만들 수있는 기회를 갖고 싶다. 정말 나쁜 생각인가요?

다시 말해, 정의되지 않은 재 할당으로부터 보호하는 방법을 묻는 것이 아닙니다 . 나는 그 트릭이 이미 100 번 쓰여진 것을 보았다. 그 속임수를 사용하지 않는 것이 얼마나 위험한지 묻고 있습니다.


7
나는 기뻐할 것이지만 주어진 세 가지 대답 중 어느 것도 질문에 대한 대답을 잘하지 못한다고 생각합니다. 나는 내가 연결 한 답변의 재해시를 요구하지 않았다는 것을 분명히하려고 노력했지만 여전히 내가 얻은 것입니다. 내가 요청한 것이 아닌데도 대답을 받아들이지 않는 것이 gauche라고 생각되면 알려 주시면 계속해서 받아 드리겠습니다!
Cosmologicon

1
그래도 모든 사실이 여기에 나와 있다고 생각합니다. 그래서, 당신이 말하는 것은 주관적인 대답이나 의견을 원한다는 것입니다. 이것이 질문 제목에 "모범 사례"라는 문구가 허용되지 않는 이유입니다. 당신은 당신의 시나리오에서 그것이 얼마나 위험한지 알 수있는 유일한 사람입니다. 그리고 모든 '변수'를 제어하지 않는 인기있는 라이브러리를 작성하는 경우 function (undefined) {} ​​래퍼가 훌륭한 대답 인 것 같습니다. 왜 그것을 사용하고 그 대답을 받아들이지 않습니까?
shannon jul.

4
사람의 사람의 재정에 대해 걱정하는 경우 undefined, 당신은 누군가의 재정의에 대해 더 걱정해야 XMLHttpRequest하거나 alert. 우리가 사용하는 모든 함수는 window재정의 될 수 있습니다. 동료가 우연히 일을하는 것에 대해 걱정이된다면, 왜 그렇게하지 말라고 믿 window.addEventListener = "coolbeans"습니까? 대답은 그것에 대해 걱정하지 않는 것입니다. 누군가가 당신의 페이지에 악의적으로 JS를 주입하고 있다면, 당신은 어찌 됐든 겁에 질려 있습니다. 처음부터 그러한 일이 발생 하지 않도록 노력하십시오.
Chris Middleton

답변:


57

아뇨. 이것은 주로 ECMAScript 5와 호환되는 최신 브라우저에서 개발하기 때문입니다. ES5 표준 undefined은 현재 읽기 전용 임을 나타냅니다 . 엄격 모드를 사용하는 경우 (필요한 경우) 실수로 수정하려고하면 오류가 발생합니다.

undefined = 5;
alert(undefined); // still undefined
'use strict';
undefined = 5; // throws TypeError

당신이해야합니까 하지 IS 자신 범위의를 생성 할, 변경할 수 undefined:

(function (undefined) {
    // don't do this, because now `undefined` can be changed
    undefined = 5;
})();

상수는 괜찮습니다. 여전히 불필요하지만 괜찮습니다.

(function () {
    const undefined = void 0;
})();

첫 번째 진술은 개발 중에 정의되지 않은 것을 실수로 덮어 쓰지 않도록 보장 할 뿐이며 클라이언트 컴퓨터에서 다른 코드로 실행할 때 동일한 위협을가합니다.
bennedich

1
@bennedich : 알아요, 저는 그 문제에 부딪힌 적이 없다고 말했지만, 여기에 당신이해야 할 일이 있습니다.
Ry-

1
@bennedich 실수로 다른 변수를 덮어 쓸 가능성이 같지 않습니까?
Ates Goral

40

적절한 코드는 그런 일을 할 수 없습니다. 하지만 똑똑한 개발자 나 사용중인 플러그인 / 라이브러리 / 스크립트가 무엇을했는지 결코 알 수 없습니다. 반면에 최신 브라우저는 덮어 쓰기 undefined를 전혀 허용하지 않으므로 개발을 위해 이러한 브라우저를 사용하는 경우 코드를 덮어 쓰려는 경우 신속하게 알 수 있습니다.


그리고 비록 당신이 그것을 요구하지 않았음에도 불구하고-많은 사람들은 아마도 더 일반적인 "재정의 된 보호 방법 undefined"문제를 찾을 때이 질문을 발견 할 것입니다 . 그래서 어쨌든 대답하겠습니다 :

브라우저의 수명에 undefined 관계없이 진정으로 정의되지 않은 상태 를 얻을 수있는 아주 좋은 방법 이 있습니다.

(function(undefined) {
    // your code where undefined is undefined
})();

지정되지 않은 인수는 항상이므로 작동합니다 undefined. 예를 들어 jQuery를 사용할 때 이와 같이 실제 인수를 받아들이는 함수를 사용하여 수행 할 수도 있습니다. 일반적으로 다음과 같은 방식으로 정상적인 환경을 유지하는 것이 좋습니다.

(function($, window, undefined) {
    // your code where undefined is undefined
})(jQuery, this);

그런 다음 익명 함수 내부에서 다음 사항이 참인지 확인할 수 있습니다.

  • $ === jQuery
  • window === [the global object]
  • undefined === [undefined].

그러나 참고 때로는 typeof x === 'undefined'실제로 필요 : 변수는 경우 x값 (인 반대에 설정되지 않았어요 세트 로를 undefined읽기) x과 같은 다른 방법으로 if(x === undefined)오류가 발생합니다. 그러나 이것은 객체 속성에는 적용되지 않으므로 그것이 y항상 객체 라는 것을 알고 있다면 if(y.x === undefined)완벽하게 안전합니다.


2
x값으로 설정되지 않는다는 귀하의 진술은 사실이 아닙니다 ( jsfiddle.net/MgADz 참조 ). 오히려 실제로 정의되지 않은 경우입니다 ( jsfiddle.net/MgADz/1 참조 ).
Ry-

7
다시 말하지만 누군가 실수로 undefined = someVariable그것이 버그 라고 말하고 당신 일이 깨지기 를 원합니다 . 적어도 나는 그렇습니다.
Cosmologicon

2
정의되지 않은 것을 덮어 쓰는 축소 된 레거시 스크립트가있는 코드베이스로 작업했습니다. 스크립트를 다시 작성할 시간이나 예산이 없었습니다. 이것은 typeof x == "undefined"가 필요한 예제입니다. 이상하지 않고 아마도 좋은 습관.
Damen TheSifter

2
모든 예제가 함수의 추가 인수로 "정의되지 않음"을 사용하는 이유에 관심이 있습니까? 그러나 누군가가 오류로 하나의 추가 매개 변수 (정의 됨)를 전달하고 모든 논리가 실패하면 상황이 발생할 수 있습니다. function () {var _undef; if (someVal == _undef) {무언가}};
Oleksandr_DJ

4
@Oleksandr_DJ 맞아요. 당신은 그 값 메이크업 알고 있다 undefined그것과 할당 undefined범위를. "너무 많은"인수를 전달하는 경우 덮어 쓰기를 위해 undefined열어 두지 마십시오 . 이는 오류를 유발하고 본질적으로 방어 적이 지 않은 패턴입니다. 특히 Lucero가 지적했듯이undefined 범위에서 확실한 값 을 얻을 수있는 매우 쉬운 대안이있을 때 그렇습니다 .
ruffin 2014

19

그것에 대한 간단한 해결책이 있습니다 : void 0항상 정의되지 않은 것과 비교하십시오 .

==값을 강제 할 수 있으므로 피해야 합니다. 대신 ===(및 !==)을 사용하십시오 .

즉, 정의되지 않은 변수는 무언가를 비교할 때 =대신 누군가가 쓰는 경우 오류로 설정 될 수 있습니다 .==undefined


IMO, 이것이 최선의 답변입니다.
abhisekp

1
호환성 표 에서 볼 수 있듯이 foo === void 0매끄럽게 읽히지 않을 수 있으며 foo === undefined불변 undefined이 최신 브라우저 (IE 9+)에서 완전히 지원 된다는 점을 고려 하십시오 .
Daniel AR Werner

3

어떤 코드를 사용하는지, 따라서 얼마나 위험한지 아는 사람 만 있습니다. 이 질문에 대한 답변은 귀하가 원하는 방식으로 답변 할 수 없습니다.

1) 팀 정책을 만들고 정의되지 않은 재정의를 허용하지 않고 더 많이 사용하도록 예약합니다. 정의되지 않은 왼쪽 할당에 대해 기존 코드를 스캔하십시오.

2) 모든 시나리오를 제어하지 않고 코드가 사용자 또는 정책이 제어하는 ​​상황 외부에서 사용되는 경우 분명히 대답이 다릅니다. 스크립트를 사용하는 코드를 스캔하십시오. 원하는 경우 정의되지 않은 왼쪽 할당에 대한 통계를 웹에서 검색하지만 대신 여기에서 # 1 또는 # 3 답을 추구하는 것이 더 쉽기 때문에 이것이 당신을 위해 이루어진 것 같지 않습니다.

3) 그리고 그 대답이 충분하지 않다면 아마도 다른 대답이 필요하기 때문일 것입니다. 회사 방화벽 내에서 사용될 인기있는 라이브러리를 작성하고 있으며 호출 코드에 액세스 할 수 없습니다. 그런 다음 여기에 다른 훌륭한 답변 중 하나를 사용하십시오. 인기있는 jQuery 라이브러리는 사운드 캡슐화를 실행하고 시작합니다.

(function( window, undefined ) {

당신이 찾고있는 특정 방식으로 당신의 질문에 답할 수 있습니다. 더 할 말은 무엇입니까?

편집 : 추신 당신이 정말로 내 의견을 원한다면, 나는 그것이 전혀 위험하지 않다고 말할 것입니다. 결함을 유발할 가능성이 매우 높은 모든 것 (예 : 정의되지 않은 것에 할당하는 것은 명백히 잘 문서화 된 위험한 행동) 그 자체가 결함입니다. 위험은 결함입니다. 하지만 그것은 제 시나리오에 불과합니다. 그 관점을 유지할 수있는 여유가 있습니다. 제가 추천하는대로 제 사용 사례에 대한 질문에 답했습니다.


3

undefined에 대해 테스트하는 것이 안전합니다. 이미 언급했듯이. 이를 재정의하는 코드 (매우 즉흥적 임)에 도달하면 더 이상 사용하지 마십시오.

어쩌면 당신은 공공 사용을위한 라이브러리를 작성하는 경우, 사용자의 변화에게 그것을 방지하기 위해 몇 가지 기술을 사용할 수 있습니다. 그러나이 경우에도 도서관이 아니라 그들의 문제입니다.


2

undefinedECMAScript 5.1을 지원하는 브라우저 용으로 코딩 할 때 언어 사양에 따라 변경할 수 없으므로 코드에서 사용할 수 있습니다 .

또한 모든 최신 브라우저 (IE 9+)가 immutable을 구현 했는지 확인하려면 호환성 표 또는 캐니 우스 ECMAScript 5 를 참조하십시오 .undefined


1

전혀 위험하지 않습니다. ES3 엔진에서 실행할 때만 덮어 쓸 수 있으며 더 이상 사용되지 않을 것입니다.


0

우선, 코드가 깨지면 다른 개발자가 "멍청이가 되려고"하기 때문이 아닐 것입니다.

undefined키워드가 아닌 것은 사실입니다 . 그러나 그것은 이다 원시적 글로벌 수준. 다음과 같이 사용하도록 의도되었습니다 ( developer.mozilla.org 에서 "undefined"참조 ).

var x;
if (x === undefined) {
    // these statements execute
}
else {
    // these statements do not execute
}

그것에 대한 일반적인 대안 (또한 MDN에서 )과 내 생각에 더 나은 방법은 다음과 같습니다.

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
    // these statements execute
}

if(x === undefined){ // throws a ReferenceError

}

몇 가지 장점이 있지만 (주석에서) 분명한 점은 x가 선언되지 않은 경우 예외를 트리거하지 않는다는 것입니다. MDN은 또한 사용하는 것이 중요하다고 지적 지적 가치 또한 그것의 ===를 통해 ==첫 번째 경우로 인해으로는 :

var x=null;
if (x === undefined) {
    // this is probably what you meant to do
    // these lines will not execute in this case
}
else if (x == undefined) {
    // these statements will execute even though x *is* defined (as null)
}
else {
    // these statements do not execute
}

이것은 모든 경우에 두 번째 대안을 사용하는 것이 더 좋은 이유 중 하나입니다.

결론 : 첫 번째 방법으로 코딩하는 것은 잘못이 아니며 위험하지도 않습니다. (덮어 쓸 수 있다는) 예제로 사용했던 주장은 typeof. 그러나 사용 typeof은 특히 ​​한 가지 이유로 더 강력합니다. var가 선언되지 않은 경우 예외가 발생하지 않습니다. ==대신 대신 사용 ===하는 것은 예상 한대로 작동하지 않는 일반적인 실수라고 주장 할 수 있습니다 . 그렇다면 왜 사용하지 typeof않습니까?


1
"두 가지 장점이 있지만 분명한 점은 x가 선언되지 않은 경우 예외를 트리거하지 않는다는 것입니다." 이걸 똑바로하겠습니다. 선언되지 않은 변수를 사용할 때 발생하는 예외를 조용히 무시 하는 것이 장점 이라고 생각 하십니까? 오류가 발생하기 쉬운 것 같습니다. 그것이 끔찍한 단점이 아니라고 생각하는 이유를 설명해 주시겠습니까?
Cosmologicon 2015
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.