변수 선언 사이에 차이점이 있습니까?
var a=0; //1
…이 방법:
a=0; //2
…또는:
window.a=0; //3
글로벌 범위에서?
답변
그렇습니다. 몇 가지 차이점이 있지만 실제로는 큰 차이가 없습니다.
네 번째 방법이 있으며 ES2015 (ES6) 기준으로 두 가지가 더 있습니다. 마지막에 네 번째 방법을 추가했지만 # 1 뒤에 ES2015 방법을 삽입 했으므로 이유를 알 수 있습니다.
var a = 0; // 1
let a = 0; // 1.1 (new with ES2015)
const a = 0; // 1.2 (new with ES2015)
a = 0; // 2
window.a = 0; // 3
this.a = 0; // 4
그 진술은 설명했다
#1 var a = 0;
이것은 또한의 한 속성입니다 전역 변수 생성 전역 객체 우리가 접근, window브라우저에서을 (또는 통해 this비 엄격한 코드의 글로벌 범위). 다른 속성과 달리 속성을 통해 제거 할 수 없습니다 delete.
사양 측면에서, 그것은 생성 바인딩 식별자 상의 객체 환경 기록 에 대한 지구 환경을 . 전역 객체는 전역 환경의 객체 환경 레코드에 대한 식별자 바인딩이 유지되는 위치이므로 전역 객체의 속성이됩니다. 이것이 속성이 삭제 불가능한 이유입니다. 단순한 속성이 아니라 식별자 바인딩입니다.
바인딩 (변수)은 첫 번째 코드 행이 실행되기 전에 정의됩니다 (아래의 “언제 var발생”참조).
주에 생성 된 속성은 IE8에 이전하는 것이 window아닙니다 열거 (에 표시되지 않는 for..in문). IE9, Chrome, Firefox 및 Opera에서는 열거 가능합니다.
# 1.1 let a = 0;
이것은 전역 객체의 속성 이 아닌 전역 변수를 만듭니다 . 이것은 ES2015에서 새로운 것입니다.
스펙 용어로, 환경 레코드 오브젝트가 아닌 글로벌 환경 에 대한 선언적 환경 레코드 에서 ID 바인딩을 작성합니다 . 글로벌 환경은 분할 환경 기록, 글로벌 객체 (이게 오래된 물건 모두를위한 하나의 필요에 고유 한 개체 새로운 물건 모두를위한 환경 기록) 및 다른 ( , ,과에 의해 생성 된 기능 )하지 전역 객체로 이동하십시오.letconstclass
바인딩 생성 포위 블록의 모든 단계별 코드 (전역 코드가 실행되기 전에,이 경우)을 실행하기 전에, 그러나 아니다 접근 단계별 실행이 도달 할 때까지 어떤 방법으로 let문을. 실행이 let명령문에 도달하면 변수에 액세스 할 수 있습니다. ( “참조 let및 const아래 발생”.)
# 1.2 const a = 0;
글로벌 상수를 작성합니다. 글로벌 상수는 글로벌 오브젝트의 특성이 아닙니다.
const정확히처럼 let당신이 초기화합니다 (제공해야한다는 점을 제외하고 = value일부)하고,이 생성 된 후에는 당신이 상수의 값을 변경할 수 없습니다. 표지 아래에서 let와 동일 하지만 식별자 바인딩에 값을 변경할 수 없다는 플래그가 있습니다. 사용 const은 세 가지 일을합니다.
- 상수에 할당하려고하면 구문 분석 시간 오류가 발생합니다.
- 다른 프로그래머에게 변하지 않는 특성을 문서화합니다.
- JavaScript 엔진이 변경되지 않는 것을 기반으로 최적화하도록합니다.
# 2 a = 0;
이것은 전역 객체에 대한 속성을 암시 적 으로 만듭니다 . 일반적인 속성이므로 삭제할 수 있습니다. 나는 이것을 하지 않는 것이 좋습니다 . 나중에 코드를 읽는 사람에게는 분명하지 않을 수 있습니다. ES5의 엄격 모드를 사용하는 경우, 존재하지 않는 변수에 할당하는 것은 오류입니다. 엄격 모드를 사용하는 몇 가지 이유 중 하나입니다.
그리고 흥미롭게도 IE8 및 이전 버전에서는 속성을 열거 할 수 없습니다 ( for..in구문 에는 표시되지 않음 ). 특히 아래 # 3에 나오는 것은 이상합니다.
#삼 window.a = 0;
이렇게하면 전역 객체 window를 참조 하는 전역을 사용하여 전역 객체에 대한 속성이 명시 적으로 생성 됩니다 (브라우저에서, 브라우저가 아닌 일부 환경에는 globalNodeJS 와 같은 전역 변수가 있습니다 ). 일반적인 속성이므로 삭제할 수 있습니다.
이 속성 은 IE8 및 이전 버전과 내가 시도한 다른 모든 브라우저에서 열거 가능합니다.
# 4 this.a = 0;
global this대신에 전역 객체를 참조한다는 점을 제외하고는 # 3과 정확히 같습니다 window. 엄격 모드 전역 코드에서는 this전역 객체에 대한 참조가 없기 때문에 엄격 모드에서는 작동하지 않습니다 ( undefined대신 값이 있음 ).
속성 삭제
“삭제”또는 “제거”는 무엇을 의미 a합니까? 정확히 : delete키워드 를 통해 속성을 완전히 제거하십시오 .
window.a = 0;
display("'a' in window? " + ('a' in window)); // displays "true"
delete window.a;
display("'a' in window? " + ('a' in window)); // displays "false"
delete객체에서 속성을 완전히 제거합니다. 당신은 속성에 추가로 그렇게 할 수 없습니다 window를 통해 간접적으로 var는이 delete중 하나를 자동으로 무시하거나 (자바 스크립트 구현에 당신이 엄격 모드에있어 여부에 따라) 예외가 발생합니다.
경고 : IE8 다시 (그리고 아마도 이전 버전과 깨진 “호환성”모드에서 IE9-IE11) : window허용되어 있어도 객체의 속성을 삭제할 수 없습니다 . 더 나쁜 것은 IE8 및 다른 브라우저 에서이 실험 을 시도 하면 예외가 발생합니다 . 따라서 객체 에서 삭제할 때는 방어 적이어야합니다.window
try {
delete window.prop;
}
catch (e) {
window.prop = undefined;
}
속성을 삭제하려고 시도하고 예외가 발생하면 다음으로 최선을 다하고 속성을로 설정합니다 undefined.
이것은 객체 에만 적용되며 windowIE8 및 이전 버전 (또는 깨진 “호환성”모드의 IE9-IE11) 에만 적용됩니다 . 다른 브라우저는 window위 규칙에 따라 속성 을 삭제 해도됩니다.
때 var발생
비아 정의 된 변수 var전에 문은 생성 된 모든 실행 컨텍스트에서 단계별로 코드가 실행되고, 그래서 속성이 아니라 존재 하기 전에var 문.
혼란 스러울 수 있으므로 살펴 보겠습니다.
display("foo in window? " + ('foo' in window)); // displays "true"
display("window.foo = " + window.foo); // displays "undefined"
display("bar in window? " + ('bar' in window)); // displays "false"
display("window.bar = " + window.bar); // displays "undefined"
var foo = "f";
bar = "b";
display("foo in window? " + ('foo' in window)); // displays "true"
display("window.foo = " + window.foo); // displays "f"
display("bar in window? " + ('bar' in window)); // displays "true"
display("window.bar = " + window.bar); // displays "b"
라이브 예 :
보다시피, 심볼 foo은 첫 번째 라인 전에 정의되지만 심볼 bar은 그렇지 않습니다. 를 Where var foo = "f";문이 두 가지 정말이 있습니다 : 실행되는 코드의 첫 번째 행 앞에 일어나는 기호, 정의는; 및 라인이 단계별 흐름 내에있는 경우, 그 심볼에 할당을 수행하는 단계를 포함한다. 파트가 스코프 상단으로 이동 ( ” var호이 스팅” var foo) 되었으나 foo = "f"파트가 원래 위치에 남아 있기 때문에 ” 게양”이라고합니다 . ( 빈약 한 작은 블로그에서 잘못 이해var 한 가난한 사람을 참조하십시오 .)
언제 let그리고 const어떻게
let과 const는 다른 var몇 가지 방법입니다. 질문과 관련된 방법은 정의한 바인딩이 단계별 코드가 실행되기 전에 생성되지만 또는 문에 도달 할 때까지 액세스 할 수 없다는 것 입니다.letconst
그래서 이것이 실행되는 동안 :
display(a); // undefined
var a = 0;
display(a); // 0
오류가 발생합니다.
display(a); // ReferenceError: a is not defined
let a = 0;
display(a);
다른 두 가지 방법이 있는지 let와는 const다를 var질문에 정말 관련이없는 어떤이다 :
-
var항상 (글로벌 코드 전체에, 또는이 표시되는 기능에 기능 코드를 통해) 전체 실행 컨텍스트에 적용되지만let및const단지 내에서 적용 블록 들이 나타납니다. 즉,var함수 (또는 글로벌) 범위를 갖지만,let및const블록의 범위를 갖는다. -
var a동일한 컨텍스트에서 반복 하는 것은 무해하지만let a(또는const a)let a가const a있거나 다른 또는 a 또는 avar a가있는 경우 구문 오류입니다.
여기에 있음을 보여주는 예입니다 let및 const그 블록이 실행 내에서 코드 전에 블록에 즉시 적용되지만까지 액세스 할 수 없습니다 let또는 const문 :
var a = 0;
console.log(a);
if (true)
{
console.log(a); // ReferenceError: a is not defined
let a = 1;
console.log(a);
}
두 번째 는 블록 외부에서 console.log액세스하는 대신 실패합니다 a.
주제 외 : 전체 객체를 어지럽히 지 마십시오 ( window)
window객체는 매우 속성 어수선하게됩니다. 가능하면 혼란에 추가하지 않는 것이 좋습니다. 대신에 약간의 패키지와 수출에 문자를 마무리 가장 받는 하나의 기호 window객체입니다. (나는 자주 내 보내지 않습니다 어떤 받는 문자 window당신은 당신의 문자하기 위해 모든 코드를 포함하는 함수를 사용할 수 있습니다. 개체), 그리고이 마음에 그 기능은 익명으로 할 수 있습니다 :
(function() {
var a = 0; // `a` is NOT a property of `window` now
function foo() {
alert(a); // Alerts "0", because `foo` can access `a`
}
})();
이 예에서는 함수를 정의하고 바로 ()끝까지 실행 합니다.
이런 방식으로 사용되는 함수를 범위 지정 함수 라고 합니다 . 범위 지정 함수 내에 정의 된 함수는 해당 데이터에 대한 폐쇄 이기 때문에 범위 지정 함수에 정의 된 변수에 액세스 할 수 있습니다 ( 폐쇄는 빈약 한 블로그에서 복잡하지 않습니다)를 참조하십시오 .
답변
간단하게 유지 :
a = 0
위의 코드는 전역 범위 변수를 제공합니다
var a = 0;
이 코드는 현재 범위에서 사용되는 변수를 제공합니다.
window.a = 0;
이것은 일반적으로 전역 변수와 동일합니다.
답변
<title>Index.html</title>
<script>
var varDeclaration = true;
noVarDeclaration = true;
window.hungOnWindow = true;
document.hungOnDocument = true;
</script>
<script src="external.js"></script>
/* external.js */
console.info(varDeclaration == true); // could be .log, alert etc
// returns false in IE8
console.info(noVarDeclaration == true); // could be .log, alert etc
// returns false in IE8
console.info(window.hungOnWindow == true); // could be .log, alert etc
// returns true in IE8
console.info(document.hungOnDocument == true); // could be .log, alert etc
// returns ??? in IE8 (untested!) *I personally find this more clugy than hanging off window obj
기본적으로 모든 변수가 중단되는 전역 객체가 있습니까? 예 : ‘globals.noVar 선언’
답변
TJ Crowder 의 탁월한 답변을 바탕으로 : ( 주제 : 혼란을 피하십시오window )
이것은 그의 아이디어의 예입니다.
HTML
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="init.js"></script>
<script type="text/javascript">
MYLIBRARY.init(["firstValue", 2, "thirdValue"]);
</script>
<script src="script.js"></script>
</head>
<body>
<h1>Hello !</h1>
</body>
</html>
init.js ( 이 답변을 기반으로 함 )
var MYLIBRARY = MYLIBRARY || (function(){
var _args = {}; // private
return {
init : function(Args) {
_args = Args;
// some other initialising
},
helloWorld : function(i) {
return _args[i];
}
};
}());
script.js
// Here you can use the values defined in the html as if it were a global variable
var a = "Hello World " + MYLIBRARY.helloWorld(2);
alert(a);
다음은 plnkr 입니다. 그것이 도움이되기를 바랍니다!
답변
전 세계적으로 의미 상 차이는 없습니다.
그러나 a=0값을 선언되지 않은 변수로 설정하므로 실제로 피해야 합니다.
또한 전역 범위를 전혀 편집하지 않으려면 클로저를 사용하십시오.
(function() {
// do stuff locally
// Hoist something to global scope
window.someGlobal = someLocal
}());
항상 필요한 경우 클로저를 사용하고 항상 글로벌 범위로 호이스트하십시오. 어쨌든 대부분의 통신에 비동기 이벤트 처리를 사용해야합니다.
@AvianMoncellor가 언급했듯이 var a = foo파일 범위에 대한 전역을 선언 하는 IE 버그가 있습니다. 이것은 IE의 악명 높은 깨진 통역사와 관련된 문제입니다. 이 버그는 친숙하게 들리므로 아마도 사실 일 것입니다.
그러니까 window.globalName = someLocalpointer
답변
