Javascript 의 delete 소개

11557 단어
질문
다음 코드 를 살 펴 보 겠 습 니 다. 주의해 야 할 것 은 다음 코드 가 브 라 우 저의 개발 자 도구 (예 를 들 어 FireBug, Chrome Developer tool) 에서 실행 되 지 않도록 하 는 것 입 니 다. 그 이 유 는 다음 과 같 습 니 다.
왜 우 리 는 대상 의 속성 을 삭제 할 수 있 습 니까?
 
  
var o = { x: 1 };
delete o.x; // true
o.x; // undefined  

그러나 이러한 성명 의 변 수 를 삭제 하지 않 습 니 다:
 
  
var x = 1;
delete x; // false
x; // 1

이렇게 정 의 된 함수 도 삭제 할 수 없습니다:
 
  
function x(){}
delete x; // false
typeof x; // "function"

메모: delete 연산 자가 true 로 돌아 갈 때 삭제 할 수 있 음 을 표시 하고 false 로 돌아 가면 삭제 할 수 없 음 을 표시 합 니 다.
이 점 을 이해 하려 면 먼저 변수 실례 화 와 속성 특성 과 같은 개념 을 파악 해 야 합 니 다. - 안 타 깝 게 도 이러한 내용 은 일부 자바 script 의 책 에서 거의 언급 되 지 않 습 니 다.이해 하 는 것 은 어렵 지 않다. 왜 이렇게 움 직 이 는 지 신경 쓰 지 않 는 다 면 이 부분 을 마음대로 뛰 어 넘 을 수 있다.
코드 종류
ECMAScript 에는 세 가지 유형의 실행 가능 코드 가 있 습 니 다. Global code (전역 코드), Function code (함수 코드) 와 Eval code (Eval 에 실 행 된 코드) 입 니 다.
 
  
var x=1;//Global code
function test(){
var y=2;//Function Code
eval("var z=3");//Eval Code in Function
}
eval("function evalTest(){}");//Eval Code in Global

상하 문
ECMAScript 코드 가 실 행 될 때 항상 일정한 컨 텍스트 에서 실 행 됩 니 다. 컨 텍스트 를 실행 하 는 것 은 추상 적 인 실체 입 니 다. 이것 은 우리 가 역할 영역 과 변 수 를 예화 하 는 방법 을 이해 하 는 데 도움 이 됩 니 다.세 가지 유형의 실행 가능 코드 에 대해 서 는 모두 실행 가능 한 문맥 이 있 습 니 다.함수 가 실 행 될 때 함수 코드 (Function code) 에 들 어 가 는 실행 컨 텍스트 를 제어 한다 고 할 수 있 습 니 다.전역 코드 가 실 행 될 때 전역 코드 (Global code) 의 실행 컨 텍스트 에 들 어 갑 니 다.
보시 다시 피 상하 문 논 리 를 실행 하 는 것 은 창고 에서 온 것 입 니 다.먼저 자신의 역할 영역 이 있 는 전역 코드 일 수 있 습 니 다. 코드 에서 함 수 를 호출 할 수 있 습 니 다. 이것 은 자신의 역할 영역 이 있 고 함 수 는 다른 함 수 를 호출 할 수 있 습 니 다. 등등.함수 가 자신 을 재 귀적 으로 호출 하 더 라 도 모든 호출 은 새로운 실행 컨 텍스트 에 들 어 갑 니 다.
4. Activation object (활성화 대상) / Variable object (변수 대상) 의 모든 실행 컨 텍스트 는 그 내부 에 Variable Object 가 있 습 니 다.실행 컨 텍스트 와 유사 하 게 Variable object 는 추상 적 인 실체 로 변 수 를 예화 하 는 메커니즘 을 묘사 합 니 다.재 미 있 는 것 은 코드 에 설 명 된 변수 와 함수 가 실제로 이 변수 대상 의 속성 으로 추가 되 었 다 는 것 이다.
전역 코드 의 실행 컨 텍스트 에 들 어 갈 때 전역 대상 은 변수 대상 으로 사 용 됩 니 다.이것 이 바로 전체 범위 에서 설명 한 변수 나 함수 가 전체 대상 의 속성 이 된 이유 입 니 다.
 
  
/* remember that `this` refers to global object when in global scope */
var GLOBAL_OBJECT = this;

var foo = 1;
GLOBAL_OBJECT.foo; // 1
foo === GLOBAL_OBJECT.foo; // true

function bar(){}
typeof GLOBAL_OBJECT.bar; // "function"
GLOBAL_OBJECT.bar === bar; // true

전역 변 수 는 전역 대상 의 속성 이 되 었 습 니 다. 그러나 함수 코드 (Function code) 에서 정의 하 는 부분 변 수 는 어떻게 될까요?행동 은 사실 매우 비슷 하 다. 그것 은 변수 대상 의 속성 이 되 었 다.유일한 차 이 는 함수 코드 (Function code) 에서 변수 대상 이 전역 대상 이 아니 라 이른바 활성화 대상 (Activation object) 이라는 점 이다.함수 코드 (Function code) 가 실행 역할 영역 에 들 어 갈 때마다 활성화 대상 (Activation object) 을 만 듭 니 다.
함수 코드 (Function code) 의 변수 와 함수 가 활성화 대상 의 속성 이 될 뿐만 아니 라 함수 의 매개 변수 (형 삼 과 대응 하 는 이름) 와 특정한 Arguments 대상 도 마찬가지 입 니 다.활성화 대상 은 내부 메커니즘 으로 프로그램 코드 에 진정 으로 접근 하지 않 습 니 다.
 
  
(function(foo){

var bar = 2;
function baz(){}

/*
In abstract terms,

Special `arguments` object becomes a property of containing function's Activation object:
ACTIVATION_OBJECT.arguments; // Arguments object

...as well as argument `foo`:
ACTIVATION_OBJECT.foo; // 1

...as well as variable `bar`:
ACTIVATION_OBJECT.bar; // 2

...as well as function declared locally:
typeof ACTIVATION_OBJECT.baz; // "function"
*/

})(1);

마지막 으로 Eval 코드 (Eval code) 에서 설명 하 는 변 수 는 호출 중인 컨 텍스트 의 변수 대상 의 속성 으로 만 들 어 졌 습 니 다.Eval 코드 (Eval code) 는 컨 텍스트 를 실행 하고 있 는 변수 대상 만 사용 합 니 다.
 
  
var GLOBAL_OBJECT = this;

/* `foo` is created as a property of calling context Variable object,
which in this case is a Global object */

eval('var foo = 1;');
GLOBAL_OBJECT.foo; // 1

(function(){

/* `bar` is created as a property of calling context Variable object,
which in this case is an Activation object of containing function */

eval('var bar = 1;');

/*
In abstract terms,
ACTIVATION_OBJECT.bar; // 1
*/

})();

5. 속성 특성 은 현재 변수 가 어떻게 될 지 잘 알 고 있 습 니 다. 나머지 유일한 이해 해 야 할 개념 은 속성 특성 입 니 다.모든 속성 은 다음 그룹의 속성 중 0 개 이상 의 특성 이 있 습 니 다. - ReadOnly, DontEnum, DontDelete 와 Internal 은 하나의 태그 이 고 속성 이 있 으 나 마 나 한 특성 이 라 고 생각 할 수 있 습 니 다.오늘 토론 의 목적 을 위해 서, 우 리 는 DontDelete 특성 에 만 관심 을 갖 는 다.
성명 의 변수 와 함수 가 변수 대상 의 속성 이 될 때 - 활성화 대상 (Function code) 이 든 전역 대상 (Global code) 이 든 생 성 된 속성 은 DontDelete 특성 을 가지 고 있 습 니 다.그러나 명확 한 (또는 함 축 된) 생 성 된 속성 은 DontDelete 특성 을 가지 고 있 지 않 습 니 다.이것 이 바로 우리 가 왜 일부 속성 을 삭제 할 수 있 고, 일 부 는 삭제 할 수 없 는 것 입 니까?
 
  
var GLOBAL_OBJECT = this;

/* `foo` is a property of a Global object.
It is created via variable declaration and so has DontDelete attribute.
This is why it can not be deleted. */

var foo = 1;
delete foo; // false
typeof foo; // "number"

/* `bar` is a property of a Global object.
It is created via function declaration and so has DontDelete attribute.
This is why it can not be deleted either. */

function bar(){}
delete bar; // false
typeof bar; // "function"

/* `baz` is also a property of a Global object.
However, it is created via property assignment and so has no DontDelete attribute.
This is why it can be deleted. */

GLOBAL_OBJECT.baz = 'blah';
delete GLOBAL_OBJECT.baz; // true
typeof GLOBAL_OBJECT.baz; // "undefined"

6. 내 장 된 속성 과 DontDelete
한 마디 로 속성 중 하나의 독특한 특성 (DontDelete) 은 이 속성 이 삭 제 될 수 있 는 지 여 부 를 제어 합 니 다.대상 의 내 장 된 속성 (즉 대상 의 미리 정 의 된 속성) 은 DontDelete 특성 이 있어 삭제 할 수 없습니다.특정한 Arguments 변수 (또는 우리 가 지금 알 고 있 는 것 처럼 대상 의 속성 을 활성화 합 니 다) 는 함수 인 스 턴 스 의 length 속성 도 DontDelete 특성 을 가지 고 있 습 니 다.
 
  
(function(){

/* can't delete `arguments`, since it has DontDelete */

delete arguments; // false
typeof arguments; // "object"

/* can't delete function's `length`; it also has DontDelete */

function f(){}
delete f.length; // false
typeof f.length; // "number"

})();

함수 매개 변수 에 대응 하 는 생 성 된 속성 도 DontDelete 특성 이 있어 삭제 할 수도 없습니다.
 
  
(function(foo, bar){

delete foo; // false
foo; // 1

delete bar; // false
bar; // 'blah'

})(1, 'blah');

7. 성명 되 지 않 은 할당
간단하게 설명 되 지 않 은 할당 값 이 전체 대상 에서 삭제 가능 한 속성 을 만 드 는 것 입 니 다.
 
  
var GLOBAL_OBJECT = this;

/* create global property via variable declaration; property has DontDelete */
var foo = 1;

/* create global property via undeclared assignment; property has no DontDelete */
bar = 2;// window.bar=2;

delete foo; // false
typeof foo; // "number"

delete bar; // true
typeof bar; // "undefined"

DontDelete 특성 은 속성 을 만 드 는 과정 에서 확 정 됩 니 다. 나중에 할당 값 은 기 존 속성 에 존재 하 는 특성 을 수정 하지 않 습 니 다. 이 점 을 이해 하 는 것 이 중요 합 니 다.
 
  
/* `foo` is created as a property with DontDelete */
function foo(){}

/* Later assignments do not modify attributes. DontDelete is still there! */
foo = 1;
delete foo; // false
typeof foo; // "number"

/* But assigning to a property that doesn't exist,
creates that property with empty attributes (and so without DontDelete) */

this.bar = 1;
delete bar; // true
typeof bar; // "undefined"

8. Eval code 가 Eval 에서 만 든 변수 나 방법 이 특별 합 니 다. DontDelete 특성 이 없 으 면 삭제 할 수 있 습 니 다.
 
  
eval("var x = 1;");
console.log(x); // 1
delete x;
console.log(typeof x); // undefined

eval("function test(){ var x=1; console.log(delete x);/* false */;return 1;}");
console.log(test()); // 1
delete test;
console.log(typeof test); // undefined  

여기 서 말 하 는 Eval 에서 만 든 변수 나 방법 은 방법 내부 의 변수 나 방법 을 포함 하지 않 습 니 다. 예 를 들 어 상기 코드 의 빨간색 부분 은 앞에서 말 한 것 과 일치 합 니 다. 삭제 할 수 없습니다.
9. FireBug 의 곤혹
FireBug 에서 실 행 된 코드 결 과 를 보 겠 습 니 다.
 
  
var x=1;
delete x;
console.log(typeof x);//undefined

function y(){
var z=1;
console.log(delete z);//false
}
y();
delete y;
console.log(typeof y);//undefined

이것 은 분명히 상술 한 규칙 을 위반 한 것 이지 만 위의 여덟 번 째 점 과 비교 해 보면 이것 은 코드 가 eval 에서 실행 되 고 있 는 효과 이다.확인 되 지 는 않 았 지만 FireBug (Chrome Developer tool) 의 콘 솔 코드 는 eval 로 실 행 될 것 으로 예상 합 니 다.
따라서 JS 코드 를 테스트 할 때 현재 컨 텍스트 환경 과 관련 될 때 특히 주의해 야 합 니 다.
10. delete 연산 자 삭제 대상
C + + 에 도 delete 연산 자가 있 습 니 다. 포인터 가 가리 키 는 대상 을 삭제 합 니 다.예 를 들 면:
 
  
class Object {
public:
Object *x;
}

Object o;
o.x = new Object();
delete o.x; // new Object

그러나 자 바스 크 립 트 의 delete 는 C + + 와 달리 o. x 가 가리 키 는 대상 을 삭제 하지 않 고 o. x 속성 자 체 를 삭제 합 니 다.
 
  
var o = {};
o.x = new Object();
delete o.x; // new Object
o.x; // undefined,o x  

실제 Javascript 에서 delete o. x 이후 Object 대상 은 인용 을 잃 어 쓰레기 로 회수 되 기 때문에 delete o. x 는 o. x 가 가리 키 는 대상 을 '삭제 하 는 것' 과 같 지만 이 동작 은 ECMAScript 기준 이 아니다. 즉, 어떤 실현 이 완료 되 더 라 도 Object 대상 을 삭제 하지 않 더 라 도 ECMAScript 기준 을 위반 하 는 것 은 아니다.
'삭제 대상 이 아 닌 속성 삭제' 라 는 점 은 다음 코드 를 통 해 확인 할 수 있다.
 
  
var o = {};
var a = { x: 10 };
o.a = a;
delete o.a; // o.a
o.a; // undefined
a.x; // 10, { x: 10 } a ,

또한 delete o. x 도 delete o [x] 를 쓸 수 있 고 이들 의 효 과 는 같다.
11. 삭제 할 수 없 는 다른 속성 은 위 에서 말 한 내장 속성 (즉, 미리 정 의 된 속성) 을 제외 하고 prototype 에서 설명 한 속성 도 delete 할 수 없습니다.
 
  
function C() { this.x = 42; }
C.prototype.x = 12;
C.prototype.y = 13;

var o = new C();
o.x; // 42, o.x

delete o.x; //true x
o.x; // 12, prototype o.x, delete o.x

delete o.y; //true, o o.y ,y prototype , prototype
o.y; //13

작은 매듭
자 바스 크 립 트 의 Delete 를 알 아 보 는 데 도움 이 되 었 으 면 좋 겠 습 니 다.수준 이 제한 되 어 있 기 때문에 정확 하 다 고 보장 할 수 없 으 며, 잘못 이 발견 되면 지적 을 환영 합 니 다.
원문:
  1、 http://perfectionkills.com/understanding-delete/(영어)
  2、 http://nanto.asablo.jp/blog/2008/01/09/2552470(일본어)
본문 이 처음 발행 되다.http://jscode.cnblogs.com

좋은 웹페이지 즐겨찾기