[javascript] JavaScript 변수를 설정 해제하는 방법?

JavaScript에 전역 변수가 있습니다 (실제로는 window속성이지만 중요하지는 않습니다). 이전 스크립트로 이미 채워져 있지만 나중에 그 값을 보거나 실행하기 위해 다른 스크립트를 원하지 않습니다. 한정된.

나는 some_var = undefined테스트 목적으로 작동 typeof some_var == "undefined"했지만 실제로 그것이 올바른 방법이라고 생각하지 않습니다.

어떻게 생각해?



답변

delete연산자는 객체 속성을 제거한다. 변수를 제거 할 수 없습니다. 따라서 질문에 대한 답변은 전역 변수 또는 속성이 어떻게 정의되는지에 달려 있습니다.

(1)로 만든 경우 var삭제할 수 없습니다.

예를 들면 다음과 같습니다.

var g_a = 1; //create with var, g_a is a variable 
delete g_a; //return false
console.log(g_a); //g_a is still 1

(2)없이 생성 var하면 삭제할 수 있습니다.

g_b = 1; //create without var, g_b is a property 
delete g_b; //return true
console.log(g_b); //error, g_b is not defined

기술 설명

1. 사용 var

이 경우 g_aECMAScript 사양 이 현재 범위에 첨부 된 ” VariableEnvironment “라고 부르는 참조 에 생성됩니다 . 이는 함수 var내부 를 사용하는 경우 함수 실행 컨텍스트 일 수 있습니다 (좀 더 복잡 할 수 있음) 당신이 고려할 때 let) 또는 “글로벌”코드의 경우에 VariableEnvironment는 전역 객체 (종종 부착 window).

VariableEnvironment 에 대한 참조는 일반적으로 삭제할 수 없습니다. ECMAScript 10.5 에 자세히 설명 된 프로세스 는이를 자세히 설명하지만 코드가 eval컨텍스트 (대부분의 브라우저 기반 개발 콘솔에서 사용)에서 실행 var되지 않으면 선언 된 변수는 사용할 수 없다고 말할 수 있습니다. 삭제하십시오.

2. 사용하지 않고 var

var키워드 를 사용하지 않고 이름에 값을 할당하려고 할 때 Javascript는 ECMAScript 사양에서 ” LexicalEnvironment “라고 부르는 이름으로 지정된 참조를 찾으려고합니다 . 주요 차이점은 LexicalEvironment 가 중첩되어 있다는 것입니다. 즉 LexicalEnvironment 는 상위가 있습니다 ( 무엇 인 ECMAScript 사양 통화 “외부 환경 참조”)와에 javscript가에 대한 참조를 찾는 데 실패하면 LexicalEenvironment , 그것은 부모에 보이는 LexicalEnvironment 에 설명 된대로 ( 10.3.110.2.2.1 ). 최고 수준의 LexicalEnvironment 는 ” 글로벌 환경입니다.“은 참조가 전역 객체의 속성이라는 점에서 전역 객체에 바인딩됩니다. 따라서 var현재 범위 나 외부 범위에서 키워드를 사용하여 선언되지 않은 이름에 액세스하려고하면 Javascript는 결국 속성을 가져옵니다. 의 window객체가 참조 역할을합니다. 우리가 전에 배운대로, 개체의 속성은 삭제 될 수 있습니다.

노트

  1. var선언은 “호이 스팅” 되었다는 것을 기억하는 것이 중요합니다. 즉, var선언문 에서 수행 될 수있는 값 초기화가 아닌-선언문이있는 영역의 시작 부분에서 항상 발생한 것으로 간주됩니다. . 따라서 다음 코드 a에서 VariableEnvironment 의 참조 이며 window속성이 아니며 그 값은 10코드의 끝에 있습니다.

    function test() { a = 5; var a = 10; }

  2. 위의 설명은 “엄격 모드”가 활성화되지 않은 경우입니다. “엄격 모드”를 사용하는 경우 조회 규칙이 약간 다르며 “엄격 모드”없이 창 속성으로 해결 된 어휘 참조는 “엄격 모드”에서 “선언되지 않은 변수”오류를 발생시킵니다. 나는 이것이 어디에 지정되어 있는지 이해하지 못했지만 브라우저의 작동 방식.


답변

@ scunlife의 답변은 효과가 있지만 기술적으로는

delete window.some_var; 

대상이 객체 속성이 아닌 경우 delete는 작동하지 않는 것으로 간주됩니다. 예를 들어

(function() {
   var foo = 123;
   delete foo; // wont do anything, foo is still 123
   var bar = { foo: 123 };
   delete bar.foo; // foo is gone
}());

그러나 전역 변수는 실제로 창 개체의 멤버이므로 작동합니다.

프로토 타입 체인이 관련된 경우 delete를 사용하면 프로토 타입이 아닌 대상 객체에서 속성 만 제거되므로 더 복잡해집니다. 예를 들어

function Foo() {}
Foo.prototype = { bar: 123 };
var foo = new Foo();
// foo.bar is 123
foo.bar = 456;
// foo.bar is now 456
delete foo.bar;
// foo.bar is 123 again.

그러므로 조심 해주시길 바랍니다.

편집 : 내 대답은 다소 정확하지 않습니다 (끝의 “오해”참조). 링크는 모든 세부 사항을 설명하지만 요약은 브라우저와 삭제하는 객체에 따라 큰 차이가있을 수 있습니다. delete object.someProp일반적으로 안전해야합니다 object !== window. var올바른 환경에서 할 수 는 있지만 선언 된 변수를 삭제하는 데 여전히 사용하지 않습니다 .


답변

없이 변수를 암시 적으로 선언하는 var경우 올바른 방법을 사용하는 것 delete foo입니다.

그러나 삭제 한 후에 추가와 같은 작업에서 이것을 사용하려고 ReferenceError하면 선언되지 않은 정의되지 않은 식별자에 문자열을 추가 할 수 없으므로 a 가 발생합니다. 예:

x = 5;
delete x
alert('foo' + x )
// ReferenceError: x is not defined

일부 상황에서는 false, null 또는 undefined로 지정하여 선언되어 이러한 유형의 오류가 발생하지 않도록하는 것이 더 안전 할 수 있습니다.

foo = false

참고 인 ECMAScript에서 그 null, false, undefined, 0, NaN, 또는 ''모두가 평가하는 것입니다 false. 그냥 확실히 당신이 사용 해달라고 할 !==연산자를 대신 !=형식 논리 값에 대한 검사 및 그렇지 신원 확인을 할 때 (그래서 null== falsefalse == undefined).

또한 delete참조를 “삭제”하는 것이 아니라 객체의 속성 만 직접 참조하십시오.

bah = {}, foo = {}; bah.ref = foo;

delete bah.ref;
alert( [bah.ref, foo ] )
// ,[object Object] (it deleted the property but not the reference to the other object)

변수를 선언 한 경우 var삭제할 수 없습니다.

(function() {
    var x = 5;
    alert(delete x)
    // false
})();

코뿔소에서 :

js> var x
js> delete x
false

다음과 같은 미리 정의 된 속성을 삭제할 수도 없습니다 Math.PI.

js> delete Math.PI
false

delete당신이 충분히 관심이 있다면 읽어야 할 언어와 마찬가지로 이상한 예외가 있습니다.


답변

some_var = null;

//or remove it..
delete some_var;


답변

TLDR는 (없이 간단한 변수를 정의 var, let, const)와 함께 삭제 될 수 있습니다 delete. , – 를 사용 var하면 -와 함께 또는 함께 삭제할 수 없습니다 .letconstdeleteReflect.deleteProperty

크롬 55 :

simpleVar = "1";
"1"
delete simpleVar;
true
simpleVar;
VM439:1 Uncaught ReferenceError: simpleVar is not defined
    at <anonymous>:1:1
(anonymous) @ VM439:1
var varVar = "1";
undefined
delete varVar;
false
varVar;
"1"
let letVar = "1";
undefined
delete letVar;
true
letVar;
"1"
const constVar="1";
undefined
delete constVar;
true
constVar;
"1"
Reflect.deleteProperty (window, "constVar");
true
constVar;
"1"
Reflect.deleteProperty (window, "varVar");
false
varVar;
"1"
Reflect.deleteProperty (window, "letVar");
true
letVar;
"1"

FF Nightly 53.0a1은 동일한 동작을 보여줍니다.


답변

ECMAScript 2015는 Reflect API를 제공합니다. Reflect.deleteProperty () 사용 하여 객체 속성을 삭제할 수 있습니다 .

Reflect.deleteProperty(myObject, 'myProp');
// it is equivalent to:
delete myObject.myProp;
delete myObject['myProp'];

전역 window객체의 속성을 삭제하려면

Reflect.deleteProperty(window, 'some_var');

경우에 따라 속성을 구성 할 수없는 경우 속성을 삭제할 수 없으며이 함수는 delete 연산자false 와 함께 반환 됩니다 . 다른 경우에는 다음을 반환합니다 .true

Object.defineProperty(window, 'some_var', {
    configurable: false,
    writable: true,
    enumerable: true,
    value: 'some_val'
});

var frozen = Object.freeze({ myProperty: 'myValue' });
var regular = { myProperty: 'myValue' };
var blank = {};

console.log(Reflect.deleteProperty(window, 'some_var')); // false
console.log(window.some_var); // some_var

console.log(Reflect.deleteProperty(frozen, 'myProperty')); // false
console.log(frozen.myProperty); // myValue

console.log(Reflect.deleteProperty(regular, 'myProperty')); // true
console.log(regular.myProperty); // undefined

console.log(Reflect.deleteProperty(blank, 'notExistingProperty')); // true
console.log(blank.notExistingProperty); // undefined

엄격 모드에서 실행될 때 deleteProperty기능과 delete연산자 에는 차이가 있습니다 .

'use strict'

var frozen = Object.freeze({ myProperty: 'myValue' });

Reflect.deleteProperty(frozen, 'myProperty'); // false
delete frozen.myProperty;
// TypeError: property "myProperty" is non-configurable and can't be deleted


답변

변수는 단순한 속성과 달리 속성 [[Configurable]] 을 가지므로 delete 연산자 를 통해 변수를 제거 할 수 없습니다 . 그러나이 규칙에 영향을 미치지 않는 하나의 실행 컨텍스트가 있습니다. 그것은 인 평가의 컨텍스트 :이 [구성] 속성이 변수에 대해 설정되지 않는다.