截图无法放在上边, 可以自己保存代码进行运行查看效果;

对象的属性

属性分两种: 数据属性和访问器属性;

数据属性: 数据属性包含一个保存数据的位置, 值会从这份位置读取, 也会写入到这个位置, 数据属性有4个特征描述它们的行为.

概念:

[[Configurable]]:表示属性是否可以通过delete删除并重新定义,是否可以修改它的特性,以及是否可以把它改为访问器属性。默认情况下,所有直接定义在对象上的属性的这个特性都是true,如前面的例子所示。

[[Enumerable]]:表示属性是否可以通过for-in循环返回。默认情况下,所有直接定义在对象上的属性的这个特性都是true,如前面的例子所示。

[[Writable]]:表示属性的值是否可以被修改。默认情况下,所有直接定义在对象上的属性的这个特性都是true,如前面的例子所示。

[[Value]]:包含属性实际的值。这就是前面提到的那个读取和写入属性值的位置。这个特性的默认值为undefined。

可以通过defineProperty对数据属性的控制.

const user = {
            name: 'join',
            age: 18,
        };

        // 对一个元素属性的控制
        Object.defineProperty(user, 'name', {
            value: 'join',
            // 是否可以修改属性的值
            writable: false,
            // 是否可以通过遍历循环到
            enumerable: false,
            // 是否可以删除属性, 当属性被定义为不可配置后, 就不能在变回可配置
            // 定义为false后, 不能在对此属性做任何配置的调整
            configurable: false,
        });
        console.log(user.name);
        user.name = 'li';
        console.log(user.name);
        delete user.name;
        console.log(user.name);

        // 同时对对象的多个元素做属性控制
        Object.defineProperties(user, {
            name: {
                value: 'join',
                writable: false,
                enumerable: false,
            },
            age: {
                value: '18',
                writable: false,
                enumerable: false,
            },
        });

获取属性特征

通过getOwnPropertyDescriptor获取某个属性的特征

// 获取某个属性的所有特征
        console.log(Object.getOwnPropertyDescriptor(user, 'name'));
        // 获取某个属性的某个特征
        console.log(Object.getOwnPropertyDescriptor(user, 'name').writable);
        // 获取对象的所有属性的特征
        console.log(Object.getOwnPropertyDescriptors(user));

禁止向对象添加属性

使用preventExtensions()方法可以设置是否可以向对象添加属性;

使用isExtensible()可以判断对象是否可以添加属性;

// 当返回值为true时, 可以添加属性
console.log(Object.isExtensible(user));
// 禁止向对象添加属性
        const users = {
            name: '丽丽',
            age: 19,
        };

        console.log(users);
        console.log(Object.getOwnPropertyDescriptors(users));
        // 禁止向对象添加属性;
        Object.preventExtensions(users); // 返回值为false
        // 当isExtensible(users)为true时, 可以向对象添加属性
        if (Object.isExtensible(users)) {
            users.site = 'js';
        }
        console.log(users);

访问器属性

概念:

访问器属性不包含数据值。相反,它们包含一个获取(getter)函数和一个设置(setter)函数,不过这两个函数不是必需的。在读取访问器属性时,会调用获取函数,这个函数的责任就是返回一个有效的值。在写入访问器属性时,会调用设置函数并传入新值,这个函数必须决定对数据做出什么修改。访问器属性有4个特性描述它们的行为。

❑ [[Configurable]]:表示属性是否可以通过delete删除并重新定义,是否可以修改它的特性,以及是否可以把它改为数据属性。默认情况下,所有直接定义在对象上的属性的这个特性都是true。

❑ [[Enumerable]]:表示属性是否可以通过for-in循环返回。默认情况下,所有直接定义在对象上的属性的这个特性都是true。

❑ [[Get]]:获取函数,在读取属性时调用。默认值为undefined。

❑ [[Set]]:设置函数,在写入属性时调用。默认值为undefined。

const user = {
            date: { name: 'lili', age: 19 },

            get age() {
                // 获取属性
                return this.date.age + '岁';
            },
            set age(value) {
                // 修改属性
                if (typeof value != 'number' || value < 19 || value > 100) {
                    throw new Error('年龄格式错误');
                }
                this.date.age = value;
            },
        };

使用set可以保护访问器属性的变量;

使用访问器批量设置属性

const web = {
            name: '开源',
            url: 'www',

            // 设置访问器属性
            set site(value) {
                console.log(value);
                // 使用解构赋值
                [this.name, this.url] = value.split(',');
            },

            get site() {
                return `${this.name}的网址是${this.url}.`;
            },
        };

        web.site = 'js,www.com';
        console.log(web.site);

封闭对象

使用Object.seal()封闭对象;

当对象处于封闭状态时, 当对象处于封闭状态时, 对象的"configurable" 特征为 false; 即不可添加属性, 不能删除对象的属性, 不能修改对象的特征;

'use strict';
        const user = {
            name: 'Lili',
            age: 18,
        };

        // 封闭状态
        Object.seal(user);
        // 当对象处于封闭状态时, 对象的"configurable" 特征为 false
        // 即不可添加属性, 不能删除对象的属性, 不能修改对象的特征

        console.log(Object.isSealed(user)); // 当对象处于封闭状态时会返回true
        console.log(JSON.stringify(Object.getOwnPropertyDescriptors(user), null, 2));

        // 当对象为处于封闭状态时, 对对象进行修改
        if (!Object.isSealed(user)) {
            delete user.name;
            user.site = '未处于封闭状态';
        }
        console.log(user);

冻结对象

可使用Object.freeze()冻结对象;

const user = {
            name: 'Lili',
            age: 19,
        };

        // 未冻结属性
        // Object.freeze(user);
        console.log(Object.isFrozen(user)); // 冻结状态为true

        console.log(JSON.stringify(Object.getOwnPropertyDescriptors(user), null, 2));
        // 冻结状态下不能修改属性的值, 不能删除属性, 不能添加属性
        if (!Object.isFrozen(user)) {
            delete user.name;
            user.site = '未冻结状态';
        }
        console.log(user);