>  기사  >  웹 프론트엔드  >  JavaScript의 속성과 특징에 대한 자세한 설명

JavaScript의 속성과 특징에 대한 자세한 설명

黄舟
黄舟원래의
2016-12-13 16:57:551059검색

JavaScript의 속성과 특성은 완전히 다른 개념입니다. 여기서는 JavaScript의 속성과 특성을 깊이 이해하기 위해 배운 내용을 사용하겠습니다.

주요 내용은 다음과 같습니다.

자바스크립트에서 객체의 본질, 객체와 클래스의 관계, 객체와 참조 유형의 관계를 이해합니다

방법 객체 속성 분류

속성의 특성 이해

1부: 객체의 본질 이해, 객체와 클래스 간의 관계, JavaScript의 객체와 참조 유형 간의 관계

객체의 특성: ECMA-262는 객체를 기본 값, 객체 또는 기능을 포함할 수 있는 정렬되지 않은 속성의 모음으로 정의합니다. 즉, 객체는 특별한 순서가 없는 값의 집합입니다. 객체의 각 속성이나 메서드에는 이름이 있으며 이 이름은 값에 매핑됩니다. 따라서 개체의 본질은 해시 테이블입니다. 이는 이름-값 쌍의 집합이며 값은 데이터 또는 함수일 수 있습니다.

객체와 클래스의 관계: JavaScript에서는 객체와 클래스가 관계가 없습니다. ECMAScript에는 클래스라는 개념이 전혀 없고, 그 객체도 다른 클래스 기반 언어와 다르기 때문입니다.

객체와 참조 유형의 관계: 각 객체는 참조 유형을 기반으로 생성되므로 객체와 참조 유형은 동일하지 않습니다.

2부: 객체 속성 분류

생성자 또는 객체 리터럴 메서드로 생성된 객체에는 속성과 메서드가 있습니다(속성과 메서드가 언급되는 한 해당 객체에 속해야 합니다. 객체가 언급되는 한 속성과 메소드(사용자 정의 제외)가 있어야 하며, 그 중 속성은 데이터 속성과 접근자 속성으로 나눌 수 있습니다. 차이점은 다음과 같습니다.

데이터 속성은 일반적으로 사용됩니다. 데이터 값을 저장하는 경우, 접근자 속성에는 데이터 값이 포함되지 않습니다

접근자 속성은 주로 get/set 작업에 사용됩니다

3부: 속성 특성 이해

ECMAScript는 객체 속성의 다양한 특성을 설명하기 위해 속성의 개념을 정의합니다. 즉, 특성은 속성을 설명하는 데 사용됩니다. 아래에서 각각 설명하겠습니다:

데이터 속성과 그 특성

접속자 속성과 그 특성

Object.defineProperties() 메서드를 사용하여 여러 속성을 정의하는 방법

Object.getOwnPropertyDescripter() 메소드를 사용하여 속성의 설명자를 읽어 속성의 특성을 읽는 방법

1. 데이터 속성과 그 특성

우리는 단지 데이터 속성은 데이터 값을 저장하는 데 사용되므로 데이터 속성에는 값을 읽고 쓸 수 있는 데이터 값의 위치가 있습니다. 데이터 속성에는 해당 동작을 설명하는 4가지 특성이 있습니다. ECMAScript에서는 속성의 특성에 JavaScript에서 직접 액세스할 수 없다고 규정하므로(참고: 액세스할 수 없음) 이를 두 세트의 대괄호 안에 넣습니다.

[[Configurable]]: 기본값은 true이며, a. 속성을 삭제하여 속성을 재정의할 수 있는지 여부를 나타냅니다. b. c. 데이터 속성에서 접근자 속성으로 속성을 변경하는 기능

[[Enumerable]]: 기본값은 true이며 for-in 루프를 통해 속성을 반환할 수 있는지 여부를 나타냅니다(즉, false인 경우). , for -in 루프는 해당 속성을 열거할 수 없습니다)

[[Writable]]: 기본값은 속성 값을 수정할 수 있는지 여부를 나타내는 true입니다. [[구성 가능]] at.

[[값]]: 기본값은 정의되지 않습니다. 이 값은 해당 속성의 속성 값을 읽고 이 위치에 속성 값을 쓸 수 있습니다.

참고: 위의 기본값은 아래에 소개할 Object.defineProperty() 메서드가 아닌 생성자 또는 객체 리터럴을 통해 생성된 객체가 소유한 속성을 나타냅니다.

이런 기능이 있습니다. 기본값이지만 해당 기본값이 우리가 원하는 값이 아니면 어떻게 될까요? 물론 수정이죠! Object.defineProperty() 메서드를 통해 속성의 기본 속성을 수정할 수 있습니다. 영어 정의Property는 속성을 정의한다는 의미입니다. 이 메서드는 속성이 있는 개체, 속성 이름, 설명자 개체라는 세 가지 매개 변수를 받습니다. 세 번째 매개변수 디스크립터 객체는 객체 리터럴 방식으로 생성되며, 내부의 속성과 속성값에는 실제로 수정될 특성과 속성값이 저장된다.

몇 가지 예를 들어 자세히 이해해 보겠습니다.

a

var person={};
Object.defineProperty(person,"name",{
  writable:false,
  value:"zhuzhenwei"
});
console.log(person.name);//zhuzhenwei
person.name="heting";
console.log(person.name);//zhuzhenwei

여기서는 객체 리터럴 방식을 사용하여 객체를 생성했지만, 메소드와 속성을 동시에 생성하지는 않았습니다. 대신 Object.defineProperty() 메서드를 사용하여 속성을 생성하고 기본값을 수정합니다. 여기서 writable은 false로 설정되어 있으므로 나중에 person.name을 수정하려고 하면 유효하지 않습니다.


b

var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei"
});
console.log(person.name);//zhuzhenwei
person.name="heting";
console.log(person.name);//zhuzhenwei

이 예에서는 writable:false를 삭제했는데 왜 수정할 수 없나요? 이전에 기능을 소개했을 때 처음 3개는 기본적으로 객체 생성 및 속성 생성 시 얻은 true로 설정되어 있었기 때문입니다. Object.defineProperty() 메서드를 호출하여 생성된 속성의 경우 처음 세 속성의 기본값은 false입니다.


c

var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:false
});
console.log(person.name);//zhuzhenwei
delete person.name;
console.log(person.name);//zhuzhenwei

여기서 새로 생성된 속성 이름의 속성을 configurable:false로 설정했습니다. 아래 속성 작업이 잘못되었습니다. b에 따르면 configurable, 기본값은 false이며, 제거하더라도 수정할 수 없음을 알 수 있다.


var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:true
});
console.log(person.name);//zhuzhenwei
delete person.name;
console.log(person.name);//undefined 

在这里我将默认的configurable的值由默认的false修改为了true,于是变成了可配置的,那么最后就成功删除了。

e

var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:false
});
console.log(person.name);//zhuzhenwei
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:true
});
console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)

如果之前已经设置成为了false,那么后面再改成true也是徒劳的,即:一旦把属性设置成为不可配置的,就不能再把它变回可配置了。


f

console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)
var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
});
console.log(person.name);//zhuzhenwei
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:true
});
console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)

   

这里可以说明,即使前一步我们不管默认的configurable:false,后面得到的仍是不可配置。于是,可以得出结论,为了可配置,必须在第一次调用Object.defineProperty()函数时就将默认的值修改为true。

2.访问器属性及其特性  

之前提到,访问器属性不包含数据值,他们包含一对getter函数和setter函数(这两个函数不是必须的)。在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性是,会调用setter函数并传入新值,这个函数负责决定如何处理数据。同样,由于不能通过JavaScript来直接访问得到访问器属性的特性,所以下面列出的特性将由[[]]括起来以作区分。

[[Configurable]]:默认值为true,a、表示能否通过delete删除属性从而重新定义属性 b、能否修改属性的特性 c、能够把属性由访问器属性修改为数据属性

[[Enumerable]]:默认值为true,表示能否通过for-in循环返回该属性(所以:如果为false,那么for-in循环没法枚举它所在的属性)

[[Get]]:在读取属性时调用的函数。默认值为undefined  关键:特性可以是一个函数

[[Set]]:  在写入属性时调用的函数。默认值为undefined 关键:特性可以是一个函数 由于get和set函数也属于属性的特性,那么他们就有可能(说有可能是因为这两个函数也不是必须的)出现在Object.defineproperty的第三个参数描述符对象的属性中。

注意:1.相对于数据属性,我们发现访问器属性中没有writable特性和value特性。这是因为访问器属性不包含数据值,那么我们怎么当然就不可修改属性的值(用不到writable特性),更不用考虑value了。

   2.访问器属性不能直接定义,必须是用Object.defineProperty()来定义。(通过这个规定我们就能准确地判断出访问器属性和数据属性了)

通过下面这个例子来深入理解:

var book={
  _year:2004,
  edition:1
};
Object.defineProperty(book,"year",{
  get:function(){<br>            return this._year;
  },
  set:function(newValue){
    if(newValue>2004){
      this._year=newValue;
      this.edition+=newValue-2004;
    }
  }
});
book.year=2005;
console.log(book.edition);//2

   

几个需要深入理解的地方:

1.访问器属性不能直接定义,必须使用Object.defineProperty()来定义,且该属性具有set和ger特性,于是可以判断,_year和edition是数据属性,而year是访问器属性。

2.我们看到_year这个数据属性前面是以_(下划线)开头的,这个一种常用的记号,用于表示只能通过对象方法访问的属性。从上面的例子中可以看到get相当于描述符对象的一个方法,而_year正是在这个对象方法访问的属性。而edition既可以通过对象方法访问,也可以由对象直接访问。

3.book.year表示正在读取访问器属性,这时会调用get函数,并返回了2004这个有效的值。

4.book.year=2005表示写入访问器属性,这时会调用set函数并传入新值,即将2005传给newValue,这个函数决定如何处理数据。

5.这时使用访问器属性的常见方法-即设置一个属性的值会导致其他属性发生变化。


3.如何利用Object.defineProperties()方法定义多个特性

显然,一个对象不可能只具有一个属性,因此,定义多个属性的可能性很大,于是JavaScript提供了Object.defineProperties()方法解决这个问题。这个方法接收两个参数,第一个是要定义属性所在的对象,第二个是一个对象字面量方法创建的对象,对象的属性名即为要定义的特姓名,对象的属性值又是一个对象,这个对象里的属性名和属性值分别是特性名和特性值(这里不是很好理解,看例子即可)。

var book={};
Object.defineProperties(book,{
  _year:{
    writable:true,
    value:2004
  },
  edition:{
    writable:true,
    value:1
  },
  year:{
    get:function(){
      return this._year;
    },
    set:function(){
      if(newValue>2004){
        this._year=newValue;
        this.edition+=newValue-2004;
      }
    }
  }
}); 

4.如何利用Object.getOwnPropertyDescripter()方法读取属性的描述符以读取属性的特性

  我们可以使用Object.getOwnPropertyDescripter()方法来取得给定属性的描述符。getOwnPropertyDescripter即为取得自身属性描述符的意思。这个方法接收两个参数:属性所在的对象要要读取其描述符的属性名称。返回一个对象。

  对于访问器属性而言,这个对象的属性有configurable、enumerable、get和set;

  对于数据属性而言,这个对象的属性有configurable、enumerable、writable和value。

var book={};
Object.defineProperties(book,{
  _year:{
    value:2004
  },
  edition:{
    value:1
  },
  year:{
    get:function(){
      return this._year;
    },
    set:function(){
      if(newValue>2004){
        this._year=newValue;
        this.edition+=newValue-2004;
      }
    }
  }
});
var descriptor=Object.getOwnPropertyDescriptor(book,"_year");
console.log(descriptor.value);//2004
console.log(descriptor.configurable);//false 因为通过Object.defineProperties()方法创建的属性的特性configurable enumerable都是false
console.log(typeof descriptor.get);//undefined 注意:这是数据属性,是不具有get特性的
var descriptor=Object.getOwnPropertyDescriptor(book,"year");
console.log(descriptor.value);//undefined
console.log(descriptor.enumerable);//false
console.log(typeof descriptor.get);//function get虽然是属性的一个特性,但是它也是函数

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时想要关注更多的相关内容请关注PHP中文网(www.php.cn)!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.