ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptオブジェクトのデータ属性とアクセサ属性の詳細説明

JavaScriptオブジェクトのデータ属性とアクセサ属性の詳細説明

青灯夜游
青灯夜游転載
2020-07-09 15:00:042511ブラウズ

JavaScriptオブジェクトのデータ属性とアクセサ属性の詳細説明

オブジェクトを作成するには 2 つの方法があります。1 つは new 演算子の後に Object コンストラクターを使用する方法、もう 1 つはオブジェクト リテラル メソッドを使用する方法です。以下のように

var person = new Object();
person.name = 'Nicy';
person.age = 21;
person.sayName = function() {
    console.log(this.name);
};        
var person = {
    name: 'Nicy',
    age: 21,
    sayName: function() {
        console.log(this.name);
    }
}

これらの 2 つのメソッドで作成されるオブジェクトは同じであり、同じプロパティとメソッドを持ちます。これらのプロパティには、その動作を説明する内部プロパティ記述子があります。

Object.defineProperty()

Object.defineProperty() を通じて、オブジェクトにプロパティを直接作成したり、既存のプロパティを変更したりできます. 属性。

Object.defineProperty(obj, prop, descriptor) は 3 つのパラメータを受け取ります:

obj: プロパティが配置されているオブジェクト

prop: プロパティの名前accessed

記述子: 記述子オブジェクト

記述子オブジェクトには、構成可能、列挙可能、書き込み可能、​​値、取得、設定の 6 つのプロパティが含まれています。プロパティの特性を変更するには、オブジェクトを使用する必要があります。 defineProperty() メソッド。

上記の 2 つのメソッドで追加されたオブジェクト プロパティの Boolean プロパティのデフォルト値は true です。Object.defineProperty を通じてプロパティ プロパティを変更する場合は、変更する必要があるプロパティのみを設定します。オブジェクト経由 .defineProperty によって作成されたプロパティには、デフォルト値が false のブール属性があります。

ECMAScript には、データ プロパティとアクセサー プロパティの 2 種類のプロパティがあります。

データ属性

データ属性には 4 つの属性記述子が含まれます:

[[構成可能]]: プロパティを再定義するかどうかを示します。プロパティのプロパティは変更できますか? プロパティをアクセサー プロパティに変更できますか?上記の方法で追加されたオブジェクトのプロパティは、デフォルトで true に設定されます。

[[Enumerable]] : for-in ループを通じてプロパティにアクセスできるかどうかを示します。上記の方法で追加されたオブジェクトのプロパティは、デフォルトで true に設定されます。

[[Writable]] : 属性の値を変更できるかどうかを示します。上記の方法で追加されたオブジェクトのプロパティは、デフォルトで true に設定されます。

[[値]]: この属性のデータ値が含まれており、読み取りと書き込みが可能です。上記の方法で追加されたオブジェクトのプロパティは、デフォルトでは未定義です。

Writable

var person = {};

Object.defineProperty(person, "name", {
    value: 'Nicy'
})
person.name = 'Lee';  
console.log(person.name)    // 'Nicy'

Object.defineProperty(person, "name", {
    writable: true
})
person.name = 'Lee';
console.log(person.name)    // 'Lee'

Object.defineProperty によって直接作成された書き込み可能なプロパティはデフォルトが false で、値を変更できません。このとき、名前は Lee に変更されます。非厳密モードでは使用できません。エラーが報告されますが、操作は無視されます。厳密モードでは、エラーが報告されます。

Configurable

<span style="font-size: 13px;"><span style="color: #0000ff;"></span>var person = {<br>    name: 'Nicy',<br>    age: 21,<br>    sayName: function() {<br>        console.log(this.name);<br>    }<br>}<br><br>Object.defineProperty(person, "name", {<br>    configurable: false<br>})<br><br>delete person.name;    // 操作被忽略,无法通过delete删除属性<br>Object.defineProperty(person, "name", {    // throw error<br>    configurable:true    <br>})     <br>Object.defineProperty(person, "name", {    // throw error<br>    enumerable: false<br>})  <br>Object.defineProperty(person, "name", {     // 由于writable为true,所以可以修改value<br>    value: 'Lucy'<br>})console.log(person.name)    // Lucy<br>Object.defineProperty(person, "name", {    // writable可进行true -> false的单向修改<br>    writable: false<br>})<br>Object.defineProperty(person, "name", {     // throw error<br>    value: 'Lee'<br>})<br>Object.defineProperty(person, "name", {    // throw error,此时writable不可以false -> true<br>    writable: true<br>})<span style="color: #000000;"></span></span>

configurable を要約すると、configurable が false に設定されている場合、

1. 削除によって属性を削除して再定義することはできません。プロパティ;

2. アクセサー プロパティに変換できません;

3. Configurable および enumerable は変更できません;

4. writable は一方向に変更できますfalse に設定されますが、false から true に変更することはできません。;

5. 値を変更できるかどうかは、writable に依存します。

configurable が false の場合、属性を削除するには delete を使用します。非厳密モードでは、エラーは報告されませんが、操作は無視されます。厳密モードでは、エラーが報告されます。他の機能が無効な場合、変更できないものを変更すると、エラーが報告されます。

Enumerable

enumerable は、オブジェクトのプロパティを for...in および Object.keys() で列挙できるかどうかを示します。

var person = {};
Object.defineProperty(person, "a", { value : 1, enumerable:true });
Object.defineProperty(person, "b", { value : 2, enumerable:false });
Object.defineProperty(person, "c", { value : 3 }); // enumerable defaults to false
person.d = 4; // 如果使用直接赋值的方式创建对象的属性,则这个属性的enumerable默认为true

for (var i in person) {    
  console.log(i);  
}  //  'a' 和 'd' 

Object.keys(person); // ["a", "d"]

アクセサー プロパティ

アクセサー プロパティには 4 つのプロパティ記述子が含まれます:

[[Configurable]]: 属性がdelete で属性を削除することで再定義できるか、属性の特性を変更できるかどうか、および属性をデータ属性に変更できるかどうかを確認します。オブジェクトに直接定義されたプロパティのデフォルトは true です。

[[Enumerable]] : for-in ループを通じてプロパティにアクセスできるかどうかを示します。オブジェクトに直接定義されたプロパティのデフォルトは true です。

[[Get]]: プロパティの読み取り時に呼び出される関数。デフォルトは未定義です。

[[Set]]: プロパティの書き込み時に呼び出される関数。デフォルトは未定義です。

var person = {
    name: 'Nicy',
    _age: 21,
    year: 1997,
    _year: 1997,
    sayName: function() {
        console.log(this.name);
    }
}

Object.defineProperty(person, "age", {
    get: function() {
        return this._age;
    },
    set: function(value) {
        this._age = value;
                // ...
    }
})

Object.defineProperty() で定義されたアクセサー プロパティには、設定可能で列挙可能なデフォルトが false に設定されています。

#データ プロパティとアクセサー プロパティ間の変換

##Object.getOwnPropertyDescriptor プロパティの読み取り

Object.getOwnPropertyDescriptor を使用してプロパティ記述子を取得します:

Object.getOwnPropertyDescriptor(obj, prop)

obj: プロパティが配置されているオブジェクト;

Prop: 名前アクセスするプロパティの。

データ属性-> アクセサー属性

属性属性は、既存のデータに対して、アクセサー記述子とデータ記述子のいずれか 1 つだけにすることができます。プロパティと get または set が指定されている場合、アクセサー プロパティに変換されると、そのプロパティの値と書き込み可能値は破棄されます。

次のコードは、オブジェクトの元のデータ属性 year をアクセサー属性に変換します。

*注: アクセサー属性の取得および設定では、これを使用してアクセサー属性を使用することはできません。プロパティ自体にアクセスします。そうでない場合、無限再帰が発生し、メモリ リークが発生します。

// 设置get和set其中任意一个即可转换为访问器属性
Object.defineProperty(person, "year", {
    get: function() {
//        return this,year;    // error
        return this._year;    
    },
    set: function(value) {
//             this.year = value;  // error
        this._year= value;
    }
})

var descriptor = Object.getOwnPropertyDescriptor(person, 'year');
console.log(descriptor);    // {get: ƒ, set: ƒ, enumerable: true, configurable: true}
元のデータ属性 year で、Object.defineProperty() を使用して属性の get または set を設定します。これはアクセサー属性に変換できます。

アクセサー プロパティ -> データ プロパティ

将访问器属性转换为数据属性,只需要给现有访问器属性设置value或writable这两个属性描述符中的任意一个即可,其原有的get和set就会被废弃,从而转换为数据属性。

上面为person定义的访问器属性age,通过Object.defineProperty()只设置了get和set,所以configurable默认为false,不可以将其转换为数据属性。可以在访问器属性和数据属性间相互转化的属性其configurable特性值必须为true。

如下代码,我们为person新定义一个访问器属性job,将其configurable设置为true ,并将其转换为数据属性:

Object.defineProperty(person, "job", {
    configurable: true,
    enumerable: true,
    get: function() {
        return this._job;
    },
    set: function(value) {
        this._job = value;
    }
})

// 设置value和writable其中任意一个即可转换为数据属性        
Object.defineProperty(person, "job", {
    value: 'worker',
    writable: true
})

var descriptor = Object.getOwnPropertyDescriptor(person, 'job');
console.log(descriptor);    // {value: "worker", writable: true, enumerable: true, configurable: true}

数据描述符value、writable 和访问器描述符get、set不能同时设置,否则会报错。

Object.defineProperties()

通过Object.defineProperties()可以一次性为对象定义多个属性。

var person = {};
Object.defineProperties(person, {
  name: {
    value: 'Nicy',
    writable: true
  },
  _age: {
    value: 21,
    enumerable: true,
    writable: true,
    configurable: true
  },
   age: {
    get: function() {
    return this._age;
    },
    set: function(value) {
    this._age = value;
    }
  }
});

 相关教程推荐:JavaScript视频教程

以上がJavaScriptオブジェクトのデータ属性とアクセサ属性の詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。