JavaScript对象(Object)研究_05_is、isExtensible、isFrozen、isSealed、keys、preventExtensions、seal

JavaScript对象(Object)研究_05_is、isExtensible、isFrozen、isSealed、keys、preventExtensions、seal

在JavaScript中,Object构造函数提供了一系列静态方法,用于操作和管理对象的属性和行为。本篇博客将深入探讨Object的几个重要静态方法:isisExtensibleisFrozenisSealedkeyspreventExtensionsseal

一、Object.is()

1. 基础介绍

Object.is()方法判断两个值是否是同一个值。它类似于严格比较运算符(===),但在处理NaN+0-0时有所不同。

2. 语法

Object.is(value1, value2)
  • value1:第一个要比较的值。
  • value2:第二个要比较的值。

3. 示例代码

示例1:一般比较
console.log(Object.is(25, 25));          // 输出: true
console.log(Object.is('foo', 'foo'));    // 输出: true
console.log(Object.is({}, {}));          // 输出: false(不同的对象)
示例2:处理NaN
console.log(Object.is(NaN, NaN));        // 输出: true
console.log(NaN === NaN);                // 输出: false
示例3:处理+0-0
console.log(Object.is(+0, -0));          // 输出: false
console.log(+0 === -0);                  // 输出: true

4. 返回值描述

Object.is()方法返回一个布尔值,表示两个值是否为同一个值。

5. 扩展知识点

  • 区别于===

    • Object.is(NaN, NaN)返回true,而NaN === NaN返回false
    • Object.is(+0, -0)返回false,而+0 === -0返回true
  • 使用场景

    当需要精确判断两个值是否相同,尤其是在处理NaN+0-0时,可以使用Object.is()

6. 注意事项

  • Object.is()不能替代=====,它只是提供了更精确的比较方式。
  • 在绝大多数情况下,Object.is()===的行为一致。

二、Object.isExtensible()

1. 基础介绍

Object.isExtensible()方法判断一个对象是否是可扩展的(即是否可以向对象添加新的属性)。

2. 语法

Object.isExtensible(obj)
  • obj:要检测的对象。

3. 示例代码

示例1:默认情况下,对象是可扩展的
const obj = {};
console.log(Object.isExtensible(obj));   // 输出: true
示例2:使用Object.preventExtensions()
const obj = {};
Object.preventExtensions(obj);
console.log(Object.isExtensible(obj));   // 输出: false

obj.newProp = 'value';                   // 无效操作,不能添加新属性
console.log(obj.newProp);                // 输出: undefined
示例3:密封和冻结对象
const sealedObj = Object.seal({});
console.log(Object.isExtensible(sealedObj)); // 输出: false

const frozenObj = Object.freeze({});
console.log(Object.isExtensible(frozenObj)); // 输出: false

4. 返回值描述

Object.isExtensible()方法返回一个布尔值,表示对象是否可扩展。

5. 扩展知识点

  • 不可扩展对象的特性

    • 不能添加新属性。
    • 现有属性的可配置性和可写性不受影响。
  • 如何使对象不可扩展

    • 使用Object.preventExtensions()
    • 使用Object.seal()Object.freeze()(它们也会使对象不可扩展)。

6. 注意事项

  • 只能对对象类型使用,非对象类型会被强制转换为对象,然后返回false

    console.log(Object.isExtensible(42)); // 输出: false
    
  • 在严格模式下,向不可扩展对象添加属性会抛出TypeError错误。

三、Object.isFrozen()

1. 基础介绍

Object.isFrozen()方法判断一个对象是否被冻结。冻结的对象不能添加新属性,不能删除或修改已有属性,属性的可配置性、可写性都被设置为false

2. 语法

Object.isFrozen(obj)
  • obj:要检测的对象。

3. 示例代码

示例1:默认情况下,对象不是冻结的
const obj = {};
console.log(Object.isFrozen(obj));       // 输出: false
示例2:使用Object.freeze()
const obj = { a: 1 };
Object.freeze(obj);

console.log(Object.isFrozen(obj));       // 输出: true

obj.a = 2;                               // 无效操作,不能修改属性
console.log(obj.a);                      // 输出: 1
示例3:嵌套对象的冻结
const obj = { inner: { b: 2 } };
Object.freeze(obj);

console.log(Object.isFrozen(obj.inner)); // 输出: false(内部对象未被冻结)

4. 返回值描述

Object.isFrozen()方法返回一个布尔值,表示对象是否被冻结。

5. 扩展知识点

  • 浅冻结Object.freeze()是浅冻结,只冻结对象的第一层属性,内部嵌套的对象需要手动冻结。

    function deepFreeze(obj) {
      const propNames = Object.getOwnPropertyNames(obj);
    
      for (const name of propNames) {
        const value = obj[name];
        if (typeof value === 'object' && value !== null) {
          deepFreeze(value);
        }
      }
    
      return Object.freeze(obj);
    }
    
    deepFreeze(obj);
    

6. 注意事项

  • 一个对象如果不可扩展、所有属性不可写、不可配置,则认为是冻结的。
  • 数组冻结后,无法修改其元素或长度。

四、Object.isSealed()

1. 基础介绍

Object.isSealed()方法判断一个对象是否被密封。密封的对象不能添加新属性,不能删除已有属性,但可以修改属性的值。

2. 语法

Object.isSealed(obj)
  • obj:要检测的对象。

3. 示例代码

示例1:默认情况下,对象不是密封的
const obj = {};
console.log(Object.isSealed(obj));       // 输出: false
示例2:使用Object.seal()
const obj = { a: 1 };
Object.seal(obj);

console.log(Object.isSealed(obj));       // 输出: true

obj.a = 2;                               // 可以修改属性值
console.log(obj.a);                      // 输出: 2

delete obj.a;                            // 无效操作,不能删除属性
console.log(obj.a);                      // 输出: 2

obj.b = 3;                               // 无效操作,不能添加新属性
console.log(obj.b);                      // 输出: undefined

4. 返回值描述

Object.isSealed()方法返回一个布尔值,表示对象是否被密封。

5. 扩展知识点

  • 密封对象的特性

    • 不能添加新属性或删除已有属性。
    • 现有属性的可配置性被设置为false
    • 属性的可写性不受影响,可以修改属性的值(前提是属性的writabletrue)。
  • 如何使对象密封

    • 使用Object.seal()方法。

6. 注意事项

  • 一个对象如果不可扩展、所有属性不可配置,则认为是密封的。
  • 数组密封后,无法改变其长度,也不能添加或删除元素,但可以修改现有元素的值。

五、Object.keys()

1. 基础介绍

Object.keys()方法返回一个由给定对象自身可枚举属性组成的数组,属性名以字符串形式表示。

2. 语法

Object.keys(obj)
  • obj:要返回其自身可枚举属性的对象。

3. 示例代码

示例1:获取对象的可枚举属性
const obj = { a: 1, b: 2, c: 3 };
const keys = Object.keys(obj);

console.log(keys); // 输出: ['a', 'b', 'c']
示例2:不可枚举属性
const obj = { a: 1 };
Object.defineProperty(obj, 'b', {
  value: 2,
  enumerable: false
});

const keys = Object.keys(obj);
console.log(keys); // 输出: ['a']
示例3:数组的键
const arr = ['x', 'y', 'z'];
const keys = Object.keys(arr);

console.log(keys); // 输出: ['0', '1', '2']

4. 返回值描述

Object.keys()方法返回一个数组,包含了对象自身的可枚举属性名,以字符串形式表示。

5. 扩展知识点

  • for...in循环的区别

    • for...in循环会遍历对象自身的可枚举属性和继承自原型链的可枚举属性。
    • Object.keys()只返回对象自身的可枚举属性。
  • 获取所有属性(包括不可枚举)

    • 使用Object.getOwnPropertyNames(obj)可以获取对象自身的所有属性,包括不可枚举属性。

6. 注意事项

  • 属性名的顺序:

    • 属性名的顺序是按照整数索引属性升序排列,然后是字符串属性按照创建时的顺序。
  • 不包括Symbol类型的属性。

六、Object.preventExtensions()

1. 基础介绍

Object.preventExtensions()方法让一个对象变得不可扩展,也就是不能再添加新的属性。现有属性的可配置性和可写性不受影响。

2. 语法

Object.preventExtensions(obj)
  • obj:要变为不可扩展的对象。

3. 示例代码

示例1:使对象不可扩展
const obj = { a: 1 };
Object.preventExtensions(obj);

obj.b = 2;           // 无效操作,不能添加新属性
console.log(obj.b);  // 输出: undefined

console.log(Object.isExtensible(obj)); // 输出: false
示例2:修改现有属性
obj.a = 3;           // 可以修改现有属性的值
console.log(obj.a);  // 输出: 3

delete obj.a;        // 可以删除现有属性
console.log(obj.a);  // 输出: undefined

4. 返回值描述

Object.preventExtensions()方法返回被传递的对象(即不可扩展的对象)。

5. 扩展知识点

  • 如何检测对象是否可扩展

    • 使用Object.isExtensible(obj)方法。
  • 不可扩展对象的特性

    • 不能添加新属性。
    • 可以删除已有属性。
    • 现有属性的可写性和可配置性不受影响。

6. 注意事项

  • 只能对对象类型使用,非对象类型会被强制转换为对象,然后返回该对象。

七、Object.seal()

1. 基础介绍

Object.seal()方法封闭一个对象,防止添加或删除属性。现有属性的值可以修改,但属性的可配置性会被设置为false

2. 语法

Object.seal(obj)
  • obj:要封闭的对象。

3. 示例代码

示例1:封闭对象
const obj = { a: 1 };
Object.seal(obj);

obj.b = 2;           // 无效操作,不能添加新属性
console.log(obj.b);  // 输出: undefined

delete obj.a;        // 无效操作,不能删除属性
console.log(obj.a);  // 输出: 1

obj.a = 3;           // 可以修改属性的值
console.log(obj.a);  // 输出: 3

console.log(Object.isSealed(obj)); // 输出: true

4. 返回值描述

Object.seal()方法返回被传递的对象(即被封闭的对象)。

5. 扩展知识点

  • 密封对象的特性

    • 不能添加新属性或删除已有属性。
    • 所有属性的可配置性被设置为false
    • 可以修改属性的值(如果属性的writabletrue)。
  • 如何检测对象是否被密封

    • 使用Object.isSealed(obj)方法。

6. 注意事项

  • 数组被封闭后,不能改变其长度,也不能添加或删除元素,但可以修改现有元素的值。

注意事项总结

  • Object.is():用于比较两个值是否是同一个值,特别处理了NaN+0-0的比较。返回布尔值

  • Object.isExtensible():判断对象是否可扩展(能否添加新属性)。返回布尔值

  • Object.isFrozen():判断对象是否被冻结(不能添加、删除、修改属性)。返回布尔值

  • Object.isSealed():判断对象是否被密封(不能添加或删除属性,但可修改属性值)。返回布尔值

  • Object.keys():返回对象自身的可枚举属性名数组。返回字符串数组

  • Object.preventExtensions():使对象不可扩展,不能添加新属性。返回被修改的对象

  • Object.seal():封闭对象,不能添加或删除属性,属性的可配置性被设置为false返回被修改的对象

深入理解这些方法,有助于我们更好地控制对象的属性和状态,提高代码的健壮性和可维护性。在实际开发中,善于利用这些方法,可以让我们的代码更加严谨和可靠。


参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

It'sMyGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值