js_javascript 기술의 내부 속성 및 삭제 연산자 소개

WBOY
풀어 주다: 2016-05-16 15:46:04
원래의
912명이 탐색했습니다.

Configurable을 설명하기 전에 먼저 면접 질문을 살펴보겠습니다.

a = 1;
console.log( window.a ); // 1
console.log( delete window.a ); // true
console.log( window.a ); // undefined

var b = 2;
console.log( window.b ); // 2
console.log( delete window.b ); // false
console.log( window.b ); // 2
로그인 후 복사

위 질문에서 두 가지 차이점을 볼 수 있습니다. var를 사용하여 변수를 선언하지 않은 경우 delete 키워드를 사용하여 삭제할 수 있고, var를 사용하여 변수를 선언하면 다시 가져오면 값이 정의되지 않습니다. 삭제를 사용하여 삭제할 수 없으며 검색 시 값은 여전히 ​​2입니다.

1. 연산자 삭제

삭제를 사용하여 변수나 속성을 삭제할 때 삭제에 성공하면 true를 반환하고, 그렇지 않으면 false를 반환합니다. 위의 예에서와 같이 삭제가 변수 a를 삭제할 수 없으면 false를 반환하고, 삭제가 변수 b를 성공적으로 삭제할 수 있으면 true를 반환합니다.

위의 두 가지 상황 외에도 일반적으로 사용되는 다양한 변수 중 삭제로 삭제할 수 있는 변수와 삭제할 수 없는 변수가 있습니다. delete가 왜 그런 결과를 내는지 걱정하지 마세요. 여기서는 반환 값만 살펴보겠습니다.

삭제 배열에서 요소 삭제:

// 使用for~in是循环不到的,直接忽略到该元素
// 使用for()可以得到该元素,但是值是undefined
var arr = [1, 2, 3, 4];
console.log( arr );     	// [1, 2, 3, 4]
console.log( delete arr[2] );	// true,删除成功
console.log( arr );      	// [1, 2, undefined, 4]
로그인 후 복사

함수 유형 변수 삭제:

// chrome 不能删除;火狐可以删除
function func(){
}
console.log( func );
console.log( delete func );
console.log( func );
로그인 후 복사

획득된 형식 매개변수의 개수인 function.length를 삭제합니다.

function func1(a, b){
}
console.log( func1.length );   	// 2
console.log( delete func1.length );	// true,删除成功
console.log( func1.length );   	// 0
로그인 후 복사

자주 사용하는 변수 삭제:

console.log( delete NaN );  	// false,删除失败
console.log( delete undefined );// false
console.log( delete Infinity );	// false
console.log( delete null );  	// true,删除成功
로그인 후 복사

프로토타입의 속성을 삭제하는 대신 프로토타입을 삭제하세요.

function Person(){
}
Person.prototype.name = "蚊子";
console.log( delete Person.prototype );	// false,无法删除
console.log( delete Object.prototype );	// false
로그인 후 복사

배열, 문자열의 길이를 삭제하는 경우:

var arr = [1, 2, 3, 4];
console.log( arr.length );    	// 4
console.log( delete arr.length ); 	// false,删除失败
console.log( arr.length );    	// 4

var str = 'abcdefg';
console.log( str.length );    	// 7
console.log( delete str.length ); 	// false,删除失败
console.log( str.length );    	// 7
로그인 후 복사

obj에서 속성을 삭제하는 경우:

var obj = {name:'wenzi', age:25};
console.log( obj.name );   	// wenzi
console.log( delete obj.name );	// true,删除成功
console.log( obj.name );   	// undefined
console.log( obj );      	// { age:25 }
로그인 후 복사

인스턴스 객체의 속성을 삭제할 때 삭제를 사용하여 속성을 삭제하면 인스턴스 객체 자체의 속성만 삭제되고 프로토타입의 속성은 삭제할 수 없다는 것을 다음 출력에서 ​​확인할 수 있습니다. 다시 삭제해도 삭제될 수 없습니다. 프로토타입에서 속성이나 속성의 메서드를 삭제하려면 다음과 같이 하세요. delete Person.prototype.name:

function Person(){
  this.name = 'wenzi';
}
Person.prototype.name = '蚊子';
var student = new Person();
console.log( student.name );    // wenzi
console.log( delete student.name ); // true,删除成功
console.log( student.name );    // 蚊子
console.log( delete student.name ); // true
console.log( student.name );    // 蚊子
console.log( delete Person.prototype.name );// true,删除成功
console.log( student.name );    // undefined
로그인 후 복사

2. js의 내부 속성

위의 예에서 일부 변수 또는 속성은 성공적으로 삭제될 수 있지만 다른 변수 또는 속성은 삭제할 수 없습니다. 따라서 이 변수 ​​또는 속성을 삭제할 수 있는지 여부는 어떻게 결정됩니까?

ECMA-262 5판은 JS 객체 속성(JS 엔진에서 사용되며 외부에서 직접 액세스할 수 없음)의 특성을 정의합니다. ECMAScript에는 데이터 속성과 접근자 속성이라는 두 가지 속성이 있습니다.

2.1 데이터 속성

데이터 속성은 값을 읽거나 쓸 수 있는 데이터 값이 포함된 위치를 나타냅니다. 이 속성에는 해당 동작을 설명하는 4가지 속성이 있습니다.

  • [[configurable]]: 삭제 연산자를 사용하여 삭제하고 재정의할 수 있는지 또는 접근자 속성으로 수정할 수 있는지 여부를 나타냅니다. 기본값은 true입니다.
  • [[Enumberable]]: for-in 루프를 통해 속성을 반환할 수 있는지 여부를 나타냅니다. 기본값은 true;
  • [[쓰기 가능]]: 속성 값을 수정할 수 있는지 여부를 나타냅니다. 기본값은 true;
  • [[값]]: 이 속성의 데이터 값을 포함합니다. 이 값은 읽혀지고 쓰여집니다. 기본값은 정의되지 않았습니다. 예를 들어 name 속성은 위의 인스턴스 객체 Person에 정의되어 있으며 해당 값은 'wenzi'입니다.

객체 속성의 기본 특성(기본값은 true)을 수정하려면 Object.defineProperty() 메서드를 호출하면 됩니다. 이 메서드는 속성이 위치한 객체, 속성 이름 및 설명자 객체( 구성 가능, 번호 매기기 가능, 쓰기 가능 및 값이어야 하며 하나 이상의 값을 설정할 수 있습니다.

은 다음과 같습니다.

var person = {};
Object.defineProperty(person, 'name', {
  configurable: false,	// 不可删除,且不能修改为访问器属性
  writable: false,		// 不可修改
  value: 'wenzi'			// name的值为wenzi
});
console.log( person.name);			// wenzi
console.log( delete person.name );	// false,无法删除
person.name = 'lily';
console.log( person.name );			// wenzi
로그인 후 복사

person.name 값을 삭제하거나 재설정하지 않는 것을 볼 수 있습니다. 이는 DefineProperty 함수를 호출하면 객체 속성의 특성이 수정되기 때문입니다. 더 이상 true로 수정하는 데 사용되지 않습니다(실행 시 다음 오류가 보고됩니다: Uncaught TypeError: Cannot redefine property: name);

2.2 접근자 속성

주로 getter 및 setter 함수 쌍이 포함되어 있습니다. 접근자 속성을 읽을 때 getter가 호출되어 유효한 값을 반환하고, 새 값을 쓰기 위해 setter가 호출됩니다. 속성에는 다음과 같은 4가지 특성이 있습니다.

  • [[Configurable]]: 삭제 연산자를 통해 속성을 삭제하고 재정의할 수 있는지 여부
  • [[Numberable]]: for-in 루프를 통해 이 속성을 찾을 수 있는지 여부.
  • [[Get]]: 속성을 읽을 때 자동 호출, 기본값: 정의되지 않음;
  • [[Set]]: 속성 작성 시 자동 호출, 기본값: 정의되지 않음;

접근자 속성은 직접 정의할 수 없으며 다음과 같이 DefineProperty()를 사용하여 정의해야 합니다.

var person = {
  _age: 18
};
Object.defineProperty(person, 'isAdult', {
	Configurable : false,
  get: function () {
    if (this._age >= 18) {
      return true;
    } else {
      return false;
    }
  }
});
console.log( person.isAdult ); // true
로그인 후 복사

그러나 여전히 주의가 필요한 것이 하나 있습니다. Object.defineProperty() 메서드로 속성을 설정할 때 접근자 속성(set 및 get)과 데이터 속성(writable 또는 value)을 동시에 선언할 수 없습니다. 즉, 속성에 쓰기 가능 또는 값 속성 세트가 있는 경우 이 속성은 get 또는 set을 선언할 수 없으며 그 반대의 경우도 마찬가지입니다.

다음과 같이 정의하면 접근자 속성과 데이터 속성이 동시에 존재하게 됩니다.

var o = {};
Object.defineProperty(o, 'name', {
  value: 'wenzi',
  set: function(name) {
    myName = name;
  },
  get: function() {
    return myName;
  }
});
로그인 후 복사

上面的代码看起来貌似是没有什么问题,但是真正执行时会报错,报错如下:

Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value

对于数据属性,可以取得:configurable,enumberable,writable和value;

对于访问器属性,可以取得:configurable,enumberable,get和set。

由此我们可知:一个变量或属性是否可以被删除,是由其内部属性Configurable进行控制的,若Configurable为true,则该变量或属性可以被删除,否则不能被删除。

可是我们应该怎么获取这个Configurable值呢,总不能用delete试试能不能删除吧。有办法滴!!

2.3 获取内部属性

ES5为我们提供了Object.getOwnPropertyDescriptor(object, property)来获取内部属性。

如:

var person = {name:'wenzi'};
var desp = Object.getOwnPropertyDescriptor(person, 'name'); // person中的name属性
console.log( desp );	// {value: "wenzi", writable: true, enumerable: true, configurable: true}
로그인 후 복사

通过Object.getOwnPropertyDescriptor(object, property)我们能够获取到4个内部属性,configurable控制着变量或属性是否可被删除。这个例子中,person.name的configurable是true,则说明是可以被删除的:

console.log( person.name );			// wenzi
console.log( delete person.name );	// true,删除成功
console.log( person.name );			// undefined
로그인 후 복사

我们再回到最开始的那个面试题:

a = 1;
var desp = Object.getOwnPropertyDescriptor(window, 'a');
console.log( desp.configurable ); 	// true,可以删除

var b = 2;
var desp = Object.getOwnPropertyDescriptor(window, 'b');
console.log( desp.configurable ); 	// false,不能删除
로그인 후 복사

跟我们使用delete操作删除变量时产生的结果是一样的。

3. 总结

别看一个简简单单的delete操作,里面其实包含了很多的原理!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿