Skip to content

1.对象删除某属性

要从对象中删除某个属性,你可以使用 JavaScript 中的 delete 关键字。以下是删除对象属性的示例:

js
const obj = {
  key1: 'value1',
  key2: 'value2',
  key3: 'value3'
};

// 删除属性 key2
delete obj.key2;

console.log(obj);
// 输出: { key1: 'value1', key3: 'value3' }

在上述示例中,我们使用 delete 关键字删除了 obj 对象中的 key2 属性。删除后,key2 属性将不再存在于 obj 对象中。

需要注意的是,使用 delete 删除属性时,属性会被完全移除,包括属性的值和属性本身。

还可以这样删除:

js
delete copyData[key];

2.大对象包小对象结构的遍历与截取

对象包对象:说白了就是一个大对象,里面的属性都是小对象,相比于对象数组的优势在于可以自定义键名(这个键名很可能是有用的,比如在 vue 中 v-for 中遍历的时候用 key 传给回调函数做一些构造参数等操作)

遍历

1.在 js 中直接遍历

(1)使用for...in循环: 在JavaScript中,可以使用for...in循环来遍历对象的属性。对于大对象,你可以使用for...in循环来遍历其中的小对象。以下是一个示例代码:

js
// 假设大对象为一个包含多个小对象的对象
var bigObject = {
  obj1: { name: '小对象1', value: 1 },
  obj2: { name: '小对象2', value: 2 },
  obj3: { name: '小对象3', value: 3 }
};

for (var key in bigObject) {
  if (bigObject.hasOwnProperty(key)) {
    var smallObject = bigObject[key];
    // 在此处对小对象进行操作
    console.log(smallObject.name, smallObject.value);
  }
}

上述代码使用for...in循环遍历了bigObject中的每个属性,然后通过属性名获取对应的小对象,进而对小对象进行操作。

(2)使用Object.keys()方法结合forEach(): 另一种遍历大对象中小对象的方法是使用Object.keys()方法获取对象的所有属性,然后结合ArrayforEach()方法进行迭代。以下是示例代码:

js
// 假设大对象为一个包含多个小对象的对象
var bigObject = {
  obj1: { name: '小对象1', value: 1 },
  obj2: { name: '小对象2', value: 2 },
  obj3: { name: '小对象3', value: 3 }
};

Object.keys(bigObject).forEach(function(key) { //.keys()方法获取所有的键,组成数组
  var smallObject = bigObject[key];
  // 在此处对小对象进行操作
  console.log(smallObject.name, smallObject.value);
});

上述代码使用Object.keys(bigObject)获取bigObject的所有属性,然后使用forEach()方法迭代属性数组,并获取对应的小对象进行操作。

2.在 vue 中遍历

vue
<!--这样得到的就是对象的 key,而不是 index-->
<el-form-item
              v-for="(item, key) in searchGroupForm.group1"
              :key="key"
              :label="item.label"
              :prop="key"
              :class="item.class"
              :ref="key"
              >

注意:除了可以遍历到 key,我们同样还可以遍历到索引 index,不过是第三个参数

vue
<div v-for="(item, key, index) in bigObject" :key="index">
  <p>Index: {{ index }}</p>
  <p>Key: {{ key }}</p>
  <p>Value: {{ item }}</p>
</div>

截取

  1. 需要按照一定的规则顺序截取的情况:

使用对象的属性进行排序:如果你想根据某个属性对小对象进行排序,并获取前几个,你可以使用 Object.entries() 方法将对象转换为一个数组,然后使用 Array.sort() 方法对数组进行排序,最后使用 Array.slice() 方法获取前几个元素。

js
const obj = {
  key1: { value: 10 },
  key2: { value: 5 },
  key3: { value: 8 },
  key4: { value: 3 },
  key5: { value: 12 }
};

const sortedEntries = Object.entries(obj).sort((a, b) => a[1].value - b[1].value);
const topN = sortedEntries.slice(0, 3);

const result = Object.fromEntries(topN); //把数组变为对象
console.log(result);
// 输出: { key4: { value: 3 }, key2: { value: 5 }, key3: { value: 8 } }

在上述示例中,我们根据 value 属性对小对象进行排序,并使用 slice() 方法获取前三个元素。

  1. 不需要根据规则,只是简单的截取几个:

使用 Object.keys() 获取前几个属性:如果你想获取对象中的前几个属性(不考虑属性的值),你可以使用 Object.keys() 方法获取对象的所有属性键,然后使用 Array.slice() 方法获取前几个键。

使用 Object.entries() 方法将对象转换为一个数组然后使用 Array.slice() 方法获取前几个元素,然后再用Object.fromEntries()方法将数组转换回对象

注意:Object.entries()会把对象转换为如下的二维数组的形式(第二层的数组固定有两个元素,分别为 key 和 value)

image-20230718213320003
js
const obj = {
  key1: 'value1',
  key2: 'value2',
  key3: 'value3',
  key4: 'value4',
  key5: 'value5'
};

const keys = Object.keys(obj);
const topNKeys = keys.slice(0, 3);

const result = {};
topNKeys.forEach(key => {
  result[key] = obj[key];
});

console.log(result);
// 输出: { key1: 'value1', key2: 'value2', key3: 'value3' }

const entries = Object.entries(obj);
const group1 = entries.splice(0, 3);
const group2 = entries;

const result = {
  group1: Object.fromEntries(group1),
  group2: Object.fromEntries(group2)
};

在上述示例中,我们使用 Object.keys() 方法获取对象的属性键,然后使用 slice() 方法获取前三个键,并将它们与对应的属性值放入新的对象中。

无论哪种方法,你都可以根据自己的需求进行适当的调整和修改,以获取你所需的前几个小对象。

3.获取 obj 的长度

要判断一个对象 obj 的长度(即包含的属性数量),可以使用 Object.keys() 方法获取对象的所有属性键,然后使用 length 属性获取键的数量。下面是一个示例:

js
const obj = {
  key1: 'value1',
  key2: 'value2',
  key3: 'value3'
};

const length = Object.keys(obj).length;
console.log(length);
// 输出: 3

在上述示例中,我们使用 Object.keys() 方法获取 obj 对象的所有属性键,并使用 length 属性获取键的数量。这样就能得到 obj 对象的长度,即包含的属性数量。

需要注意的是,Object.keys() 方法只返回对象自身可枚举的属性键,不包括继承的属性。如果你需要包含继承的属性,可以使用 for...in 循环或 Object.getOwnPropertyNames() 方法获取所有属性键(即自身的和原型链上的)。

for (let key in) Object.keys()Object.getOwnPropertyNames()Reflect.ownKeys()的区别:

1.for...in会遍历自身的属性和原型链上的所有属性,但是只包括可枚举的属性!

注意:在使用 for...in 循环遍历对象属性键时,你可以通过 hasOwnProperty() 方法来过滤掉原型链上的属性键,只获取对象自身的属性键。

js
const obj = { a: 1, b: 2, c: 3 };

for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key);
  }
}

2.Object.keys() 只返回对象自身属性,只包括可枚举的属性!

3.Object.getOwnPropertyNames() 只返回对象自身属性,但是包括所有可枚举和不可枚举的属性键!

——> keys()和getOwnPropertyNames()仅仅是是否返回不可枚举属性的区别!

4.使用Reflect.ownKeys方法可以获取对象的所有属性,包括可枚举和不可枚举的属性,包括原型链上继承的属性!——> 获取属性最全面的方法!

什么是可枚举和不可枚举属性?

可枚举属性和不可枚举属性的区别在于它们是否会出现在对象的属性枚举中,例如在 for...in 循环或 Object.keys() 方法中。

下面是可枚举属性和不可枚举属性之间的区别:

  1. 可枚举属性:
    • 可枚举属性是那些可以通过 for...in 循环枚举到的属性。
    • 可枚举属性会出现在对象的属性枚举中。
    • 当使用 Object.keys() 方法获取对象的属性键时,只会返回可枚举属性的键。
  2. 不可枚举属性:
    • 不可枚举属性是那些无法通过 for...in 循环枚举到的属性。
    • 不可枚举属性不会出现在对象的属性枚举中。
    • 当使用 Object.keys() 方法获取对象的属性键时,不会返回不可枚举属性的键。

在 JavaScript 中,默认情况下,大多数自定义属性是可枚举的。但是,某些内置属性和方法通常是不可枚举的。你可以使用 Object.defineProperty()Object.defineProperties() 方法显式地定义属性的可枚举性。

下面是一个示例,展示了Object.defineProperty() 或 Object.defineProperties()的区别:

js
//使用 Object.defineProperty() 方法定义或修改单个属性:
const obj = {};

Object.defineProperty(obj, 'name', {
  value: 'John',
  writable: true,
  enumerable: false, //不可枚举
  configurable: true
});

console.log(obj.name); // 输出:'John'
const obj = {};

//使用 Object.defineProperties() 方法定义或修改多个属性:
Object.defineProperties(obj, {
  name: {
    value: 'John',
    writable: true,
    enumerable: false, //不可枚举
    configurable: true 
  },
  age: {
    value: 30,
    writable: false,
    enumerable: true, //可枚举
    configurable: true
  }
});

console.log(obj.name); // 输出:'John'
console.log(obj.age); // 输出:30

总结起来,可枚举属性可以通过枚举方法和操作获取,而不可枚举属性在枚举方法和操作中被忽略。默认情况下,大多数自定义属性是可枚举的,而一些内置属性和方法通常是不可枚举的。

对于对象继承的属性的理解:(以及对象继承对象的方法)

继承的属性:继承是指一个对象通过原型链从其他对象或构造函数继承属性和方法。当一个对象继承另一个对象或构造函数时,它会获得父对象或构造函数的属性和方法。这些被继承的属性和方法可以通过原型链访问。继承的属性包括从原型对象继承的属性,以及可能来自其他原型链上的属性。

使用Reflect.ownKeys方法获取对象的所有属性,包括可枚举和不可枚举的属性,包括原型链上继承的属性!——>获取属性最全面的方法

js
function getAllPropertyKeys(obj) {
  const keys = Reflect.ownKeys(obj);
  return keys;
}

const obj = { a: 1, b: 2 };
const inheritedObj = Object.create(obj);
inheritedObj.c = 3;

const allKeys = getAllPropertyKeys(inheritedObj);
console.log(allKeys); // 输出:["c", "a", "b"]

如果属性在原型链上某个对象上找到,那么该属性就被继承到了当前对象。

以下是一个示例,展示了继承的属性:

js
const parent = { a: 1 };
const child = Object.create(parent); //Object.create() 方法以 parent 对象为原型创建了一个新对象 child。(如果是构造函数,那么就直接 new 就可以了)

console.log(child.a); // 输出:1,child 继承了 parent 的属性 "a"

在上述示例中,我们创建了一个 parent 对象,它包含属性 "a"。然后,我们使用 Object.create() 方法以 parent 对象为原型创建了一个新对象 child。由于 child 对象通过原型链继承了 parent 对象,因此它可以访问并继承 parent 对象的属性。

对象继承(原型继承)和类继承的区别?

Object.create(obj) 和类的继承之间有一些区别。

  1. 原型继承:Object.create(obj) 使用原型继承,它创建一个新对象,并将 obj 对象设置为新对象的原型。这意味着新对象可以访问 obj 对象的属性和方法。这种继承方式基于原型链,使得对象之间可以共享属性和方法。
  2. 类的继承:类的继承是基于类与实例之间的关系。在类的继承中,使用关键字 extends 可以创建一个新的类,并继承自另一个类。子类继承了父类的属性和方法,并可以添加自己的属性和方法。类继承通过类的构造函数、super 关键字和原型链来实现。

总结起来,Object.create(obj) 使用原型继承创建一个继承自 obj 对象的新对象,而类的继承是基于类与实例之间的关系,通过 extends 关键字创建一个新的类,并继承自另一个类。它们在语法、原型链、构造函数、多重继承和特性等方面有所不同。