• 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()方法也可以创建一个冻结对象。

  • 相关阅读:
    vue+iview简单实现获取要上传文件的Base64字符串
    com.microsoft.sqlserver.jdbc.SQLServerException: 必须执行该语句才能获得结果。
    Java入门2.1---面向对象的主线1---类及类的构成成分:属性、方法、构造器、代码块、内部类
    淘系自研前端研发工具 AppWorks 正式发布
    百度开源一款前端图片合成工具库:MI
    微软体验超棒的Fluent UI宣传短片,爱了爱了
    oracle的购买价格研究
    .NET Core 网络数据采集 -- 使用AngleSharp做html解析
    【译】Google Markdown书写风格指南
    我终于逃离了Node(你也能)
  • 原文地址:https://www.cnblogs.com/zhilu/p/16076965.html
Copyright © 2020-2023  润新知