Object函数的不常用的内置方法

一、Object.preventExtensions

1、定义:Object.preventExtensions()方法用于将一个对象设置为不可扩展,也就是不能再为其添加新的属性。

2、语法

Object.preventExtensions(obj);

参数

obj:要配置为不可扩展的对象

返回值

被设置为不可配置的对象

对象默认是可扩展的,即可以添加新的属性。如果一个对象被配置为不可扩展,则无法添加新的属性,这是一个不可逆的操作。不可扩展的对象仍然可以删除已有的属性(取决于属性的可配置性),但如果尝试添加新的属性到不可扩展对象,会引发TypeError异常(严格模式)或静默失败。

Object.preventExtensions()仅阻止添加自身的属性。但属性仍然可以添加到对象原型,而这个不可扩展的对象同样会继承这些后来添加的原型对象的属性。

在ES5中,如果参数不是一个对象类型,将抛出一个TypeError异常。

在ES6中,非对象参数将被视为一个不可扩展的普通对象,因此会被直接返回。

3、示例

示例1:配置对象为不可扩展

var obj = { a: 1 };
var obj2 = Object.preventExtensions(obj);
obj2 === obj; // true  方法返回的对象仍是原对象


obj.b = 2; // 非严格模式下静默失败
obj.b; // undefined

Object.defineProperty(obj, 'c', {
    value: 3,
    writable: true,
    enumerate: true,
    configuration: true
});
obj.c; // undefined

示例2:传入非对象类型的值

var str = 'abcd';
Object.preventExtensions(str); // "abcd" 直接返回

二、Object.isExtensible

1、定义:Object.isExtensible()方法用于判断一个对象是否是可扩展的。

2、语法

Object.isExtensible(obj);

参数

要判断可扩展性的对象

返回值

一个布尔值,表明对象是否可扩展。

 默认情况下,对象都是可以扩展的,即对象可以添加新的属性和方法。使用Object.preventExtensions()、Object.seal()和Object.freeze()方法都可以标记对象为不可扩展。

在ES5中,如果参数是非对象类型,会抛出TypeError异常。

在ES6中,如果参数是非对象类型,则会认为是一个不可扩展的普通对象,因此会返回false。

 3、示例

示例:测试对象的可扩展性

var obj = {};
Object.isExtensible(obj); // true

Object.preventExtensions(obj);
Object.isExtensible(obj); // false

var obj2 = Object.create(obj);
Object.isExtensible(obj2); // true  原型对象不可扩展,不会影响继承对象

var obj3 = Object.seal({});
Object.isExtensible(obj3); // false

var obj4 = Object.freeze({});
Object.isExtensible(obj4); // false

三、Object.seal

一、定义:Object.seal()方法用于密封一个对象,即将对象设置为不可扩展,同时将对象的所有自有属性都设置为不可配置(包括Symbol值的属性)。也就是说,不能给对象添加新的属性和方法,也不能删除现有的属性和方法、不能修改现有属性和方法的配置。但如果对象的属性和方法是可写的,那该属性和方法仍然可以修改。

二、语法

 

Object.seal(obj);

 

参数

obj:要被密封的对象

返回值

被密封的对象

该操作不会影响从原型对象继承来的属性和方法,即只影响自有的属性和方法。一旦对象被密封,则不能修改其属性和方法的配置,一个数据属性不能被重新定义成访问器属性,也不能从访问器属性修改为数据属性。

在ES5中,如果传递给方法的参数不是一个对象,会抛出TypeError异常。

在ES6中,如果传递给方法的参数不是一个对象,则会被视为已被密封的普通对象,直接返回它。

3、示例

示例1:密封一个对象

var obj = { 
    a: 1,
    b: function () { console.log(2); },
    [Symbol('c')]: 3
};

Object.getOwnPropertyDescriptors(obj);
/*
{
    a: {value: 1, writable: true, enumerable: true, configurable: true},
    b: {value: ƒ, writable: true, enumerable: true, configurable: true},
    Symbol(c): {value: 3, writable: true, enumerable: true, configurable: true}
}
*/

Object.seal(obj);
Object.getOwnPropertyDescriptors(obj);
/*
{
    a: {value: 1, writable: true, enumerable: true, configurable: false},
    b: {value: ƒ, writable: true, enumerable: true, configurable: false},
    Symbol(c): {value: 3, writable: true, enumerable: true, configurable: false}
}
*/

示例2:尝试修改一个密封对象

var obj = { 
    a: 1,
    b: function () { console.log(2); },
    [Symbol.for('c')]: 3
};

obj.a;  // 1
obj.b();  // 2
obj[Symbol.for('c')]; // 3

Object.seal(obj);
// 尝试删除一个属性
delete obj.a; // false, 静默失败,严格模式下TypeError
obj.a; // 1

// 尝试修改一个属性
obj.a = 10;
obj.a; // 10 修改成功,密封操作只修改属性的可配置性,不影响可写性

// 尝试修改一个方法
obj.b = function () { return 20; }
obj.b(); // 20 修改成功,密封操作只修改方法的可配置性,不影响可写性

// 尝试修改数据属性成访问器属性
Object.defineProperty(obj, 'a', {
    get: function () { return 1; }
};
// TypeError: Cannot redefine property: a

四、Object.isSealed

1、定义:Object.isSealed()方法用于判断一个对象是否是已密封的状态。密封状态是指一个对象是不可扩展的,且所有自有属性和方法都是不可配置的。

2、语法

Object.isSealed(obj);

参数

obj:要检查的对象。

返回值

返回一个布尔值,表示这个对象是否是已密封的。

在ES5中,如果传递给方法的参数不是一个对象,会抛出TypeError异常。

在ES6中,如果传递给方法的参数不是一个对象,会认为其是一个密封对象,直接返回true。

3、示例

示例1:检测一个对象是否密封

var obj = { a: 1 };
Object.isSealed(obj); // false
Object.seal(obj);
Object.isSealed(obj); // true

var obj2 = { b: 2 };
Object.preventExtensions(obj2);
Object.isSealed(obj2); // false

示例2:创建一个原生密封的对象

var obj = Object.defineProperty({}, 'a', {
    value: 1,
    enumerable: true,
    writable: true,
    configurable: false
});

Object.preventExtensions(obj);
Object.isSealed(obj); // true 注意这里没有调研Object.seal()方法

根据定义,只要对象所有自有的属性和方法是不可配置的,且对象本身是不可扩展的,即认为对象是密封的。因此,根据示例2我们可以知道,只要符合上述条件,不一定要调用Object.seal()方法也可以创建一个密封对象。

 

五、Object.freeze

1、定义:

Object.freeze()方法用于冻结一个对象。即将对象设置为不可扩展、将对象的所有自有的属性和方法(包括Symbol值的属性和方法)配置为不可配置、不可写。

 2、语法

Object.freeze(obj);

参数

obj:要冻结的对象

返回值

已冻结的对象

 

该操作不会影响从原型对象继承来的属性和方法,即只影响自有的属性和方法。一旦对象被冻结,其自身的所有属性都不可能以任何方式被修改。任何修改尝试都会失败,无论是静默地还是通过抛出TypeError异常。

3、示例

示例1:冻结一个对象

var obj = { 
    a: 1,
    b: function () { console.log(2); },
    [Symbol('c')]: 3
};

Object.getOwnPropertyDescriptors(obj);
/*
{
    a: {value: 1, writable: true, enumerable: true, configurable: true},
    b: {value: ƒ, writable: true, enumerable: true, configurable: true},
    Symbol(c): {value: 3, writable: true, enumerable: true, configurable: true}
}
*/

Object.freeze(obj);
Object.isExtensible(obj); // false
Object.getOwnPropertyDescriptors(obj);
/*
{
    a: {value: 1, writable: false, enumerable: true, configurable: false},
    b: {value: ƒ, writable: false, enumerable: true, configurable: false},
    Symbol(c): {value: 3, writable: false, enumerable: true, configurable: false}
}
*/

示例2:尝试通过setter修改冻结对象的属性值

var obj = {
    a: 1,
    get next() { return this.a++; },
    set next(value) { 
        if (value >= this.a) { 
            this.a = value;
        }
    }
};

Object.getOwnPropertyDescriptors(obj);
/*
{
    a: {value: 1, writable: true, enumerable: true, configurable: true},
    next: {get: ƒ, set: ƒ, enumerable: true, configurable: true}
}
*/

obj.next; // 1
obj.a;    // 2
Object.freeze(obj);
Object.getOwnPropertyDescriptors(obj);
/*
{
    a: {value: 2, writable: false, enumerable: true, configurable: false}
    next: {get: ƒ, set: ƒ, enumerable: true, configurable: false}
}
*/
obj.next; // 2
obj.next; // 2
obj.next; // 2
obj.a;    // 2
obj.next = 10;     // 修改失败
obj.next; // 2
obj.a;    // 2

示例3:冻结数组对象

var array = [1, 2, 3, 4, 5, 6];
Object.freeze(array);

// 尝试插入一个元素
array.push(7); // Cannot add property 6, object is not extensible

// 尝试删除一个元素
array.pop();  // Cannot delete property '5' of [object Array]

// 尝试缩小数组长度
array.length = 2; // 静默失败
array.length; // 6
array; // [1, 2, 3, 4, 5, 6];

// 尝试扩大数组长度
array.length = 10; // 静默失败
array.length; // 6
array; // [1, 2, 3, 4, 5, 6];

// 尝试修改数组已有元素
array[1] = 10;  // 静默失败
array[1]; // 2

六、Object.isFrozen

1、定义:Object.isFrozen()方法用于判断一个对象是否已冻结。

2、语法

Object.isFrozen(obj);

参数

obj:要判断是否冻结的对象。

返回值

返回一个布尔值表明对象是否已冻结。

 

在ES5中,如果传递给方法的参数不是一个对象,会抛出TypeError异常。

在ES6中,如果传递给方法的参数不是一个对象,会认为其是一个冻结对象,直接返回true。

3、示例

示例1:检测一个对象是否已冻结

var obj = { a: 1 };
Object.isFrozen(obj); // false
Object.freeze(obj);
Object.isFrozen(obj); // true

var obj2 = { b: 2 };
Object.preventExtensions(obj2);
Object.isFrozen(obj2); // false

示例2:创建一个冻结对象

var obj = Object.defineProperty({}, 'a', {
    value: 1,
    enumerable: true,
    writable: false,
    configurable: false
});

Object.defineProperty(obj, 'next', {
    get:function () { return this.a;},
    set:function (v) { this.a = v;},
    configuration: false
});

Object.preventExtensions(obj);
Object.isFrozen(obj); // true 注意这里没有调研Object.freeze()方法

根据定义,只要对象所有自有的属性和方法是不可配置和不可写的,且对象本身是不可扩展的,即认为对象是冻结的。因此,根据示例2我们可以知道,只要符合上述条件,不一定要调用Object.freeze()方法也可以创建一个冻结对象。

 

posted @ 2022-03-30 14:38  之鹿喵  阅读(33)  评论(0编辑  收藏  举报