Skip to content

对象的属性特性

读取属性的特性

js
Object.getOwnPropertyDescriptor();		返回指定对象指定属性的描述特性,第一个参数是对象,第二个参数是属性名
Object.getOwnPropertyDescriptors();		返回指定对象所有属性的描述特性,参数是对象。

读取对象上的属性

javascript
Object.getOwnPropertyNames();	返回指定对象所有属性名,参数是对象。

数据属性和访问器属性

对象的属性可以分为数据属性访问器属性,它们的描述特性是不同的。

① 数据属性

数据属性包含一个数据值的位置,我们定义对象时设置的属性都是数据属性

数据属性有如下 4 个特性:

1)Configurable:可配置性,表示能否通过 delete 删除属性,能否修改属性的特性,能否把属性修改为访问器属性,默认值为 true。

2)Enumerable:可枚举性,表示能否通过 for-in 循环返回,默认值为 true。

3)Writable:可写性,表示能否修改属性的值,默认值为 true。

4)Value:值,这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。默认值为 undefined。

js
// user 对象的属性的特性
console.log(Object.getOwnPropertyDescriptor(user, 'address'));
console.log(Object.getOwnPropertyDescriptor(user, 'say'));
console.log(Object.getOwnPropertyDescriptors(user));
console.log('');

console.log(Object.getOwnPropertyDescriptor(arr, 'length'));
console.log(Object.getOwnPropertyDescriptors(arr));
console.log('');

console.log(Object.getOwnPropertyDescriptor(window, 'name'));

可以通过下面方式设置属性的特性:

js
var person = {
    name:'高晓乐';
    address:'上海';
}; 
Object.defineProperty(person, "name", { 
 writable: false, 
 value: "Nicholas" 
});

② 访问器属性

访问器属性不包含数据值;它们包含一对儿 getter 和 setter 函数。在读取访问器属性时,会调用 getter 函数,这个函数负责返回有效的值;在写入访问器属性时,会调用 setter 函数并传入新值,这个函数负责决定如何处理数据。

访问器属性有如下 4 个特性:

1)Configurable:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。

2)Enumerable:表示能否通过 for-in 循环返回属性。

3)Get:在读取属性时调用的函数。默认值为 undefined。

4)Set:在写入属性时调用的函数。默认值为 undefined。

可以通过如下方式为对象设置访问器属性:

相当于一个拦截器

js
var book = { 
 // 下划线设置属性,不对外公开
 	_year: 2004, 
 	edition: 1 
}; 

Object.defineProperty(book, "year", { 
 get: function(){ 
   return this._year; 
 }, 
 set: function(newValue){ 
     //在这里设置条件
   	if (newValue > 2004) { 
    this._year = newValue; 
    this.edition += newValue - 2004; 
   } 
 } 
});

Object定义多个属性方法

Object.defineProperties()

Object.defineProperties() 这个方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。

javascript
Object.defineProperties(obj, props)
  /* 
  obj 在其上定义或修改属性的对象。
  props 要定义其可枚举属性或修改的属性描述符的对象。
  props对象中的 "属性" 可配置如下键值:
    configurable:true/false,
    enumerable:true/false,
    value:"", //与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。
  	writable:true/false,
  	get:function(){
  	  //当获取 "属性" 时,会自动调用 get 方法
  	  //get方法体中 return 什么,属性值就是什么
  	},
  	set:function(val){
  	  //当设置 "属性" 时,会自动调用 set 方法
  	}
  */
js
var book = {
    
}; 
Object.defineProperties(book, { 
     _year: { 
         value: 2004 
     }, 
     edition: { 
         value: 1 
     }, 
     year: { 
         get: function(){ 
             return this._year; 
         }, 
         set: function(newValue){ 
             if (newValue > 2004) { 
                 this._year = newValue; 
                 this.edition += newValue - 2004; 
             } 
         } 
 	} 
});
js
// 创建对象
        const user = {
            name: '小乐',
            _age: 0
        };
// 给 user 添加多个属性并设置属性的特性
        Object.defineProperties(user, {
            address: {
                enumerable: false,
                configurable: false,
                writable: false,
                value: '上海'
            },
            age: {
                configurable:true,
                enumerable:false,
                set: function(val) {
                    val = +val;
                    if (val >= 0 && val <= 200) {
                        this._age = val;
                    }
                },
                get: function() {
                    return this._age;
                }
            }
        });


        console.log(user.address); //上海
        console.log(user.age); //0

Object.create()

Object.create() 可以在创建新对象的同时,给对象添加属性并设置特性:

js
Object.create(Objec.prototype, {
   // foo 是一个常规数据属性
   foo: {
    writable: true,
    configurable: true,
    value: "hello",
  },
  // bar 是一个访问器属性
  bar: {
    configurable: false,
    get() {
      return 10;
    },
    set(value) {
      console.log("Setting `o.bar` to", value);
    },
});

创建一个对象,原型是Array,并设置数据属性,

js
const arr = Object.create(Array.prototype, {
            0: {
                configurable: false,
                enumerable:false,
                writable:true,
                value: '北京'
            },
            1: {
                configurable: false,
                enumerable:false,
                writable:true,
                value: '上海'
            },
            address: {
                enumerable: false,
                configurable: false,
                writable: false,
                value: '上海'
            },
            age: {
                configurable:true,
                enumerable:false,
                set: function(val) {
                    
                },
                get: function() {
                    return 100
                }
            }
        });

        console.log(arr);

Class定义访问器方法

js
//定义类
class Person {
  //定义属性
  #firstName = '尼古拉斯';
  #lastName = '赵四';

  //当获取fullName属性值的时候 自动调用
  get fullName() {
    return this.#firstName + '·' + #this.lastName;
  }

  //当设置fullName属性值的时候 自动调用  接受一个参数,是要给fullName属性设置的新值
  set fullName(val) {
    this.#firstName = val.split('·')[0];
    this.#lastName = val.split('·')[1];
  }
}
js
class Product {
            // 数据属性
            name = '高小乐';
            address = '上海';
            #age = 0;

    		// 访问器属性
            set age(val) {
                val = +val;
                if (val >= 0 && val <= 200) {
                    this.#age = val;
                }
            };

            get age() {
                return this.#age;
            }
        }

        // 实例化
        const p = new Product();

        console.log(p);
        p.age = 124;
        p.age = 1240;
        console.log(p.age);

对象的封闭和冻结

① 封闭对象

对象封闭之后,阻止添加新属性并将所有现有属性标记为不可配置。

js
Object.seal()		封闭对象
Object.isSealed()	判断对象是否被封闭
js
// 定义数组
        const arr = [10,20,30,40,50];
        arr.name = '高小乐';
        arr.address = '上海';

        封闭对象
        Object.seal(arr);

        console.log('对象是否被封闭:', Object.isSealed(arr));
        console.log('对象是否被冻结:', Object.isFrozen(arr));
        console.log('');

        // 封闭之后 不能添加新属性 旧的属性不可配置
        // 冻结之后 不能添加新属性 旧的属性不可配置 旧属性不可写
        arr.age = 100;//不可以
        delete arr.name;//不可以
        arr[0] = 250; //可以更改属性的值
        arr.address = '北京';//可以更改属性的值
        console.log(arr);

② 冻结对象

对象冻结之后,阻止添加新属性并将所有现有属性标记为不可配置,不能修改已有属性的值,该对象的原型也不能被修改。

js
Object.freeze()		冻结对象
Object.isFrozen()	判断对象是否被冻结
js
// 定义数组
        const arr = [10,20,30,40,50];
        arr.name = '高小乐';
        arr.address = '上海';

        // 冻结对象
        Object.freeze(arr);

        console.log('对象是否被封闭:', Object.isSealed(arr));
        console.log('对象是否被冻结:', Object.isFrozen(arr));
        console.log('');

        // 封闭之后 不能添加新属性 旧的属性不可配置
        // 冻结之后 不能添加新属性 旧的属性不可配置 旧属性不可写
        arr.age = 100;//不可以
        delete arr.name;//不可以
        arr[0] = 250; //不可以
        arr.address = '北京';//不可以
        console.log(arr);