属性遍历,会了又没完全会

简介: 我们来归类下,这些都属于哪些属性分类。了解属性分类以后,让我们再想想 我们又如何获取person 对象的所有属性呢??

1.JPG


1. 属性的分类



  • 普通属性
  • 原型属性
  • 不可枚举属性
  • Symbol 属性
  • 静态属性 ??


我们先来看看下面这个对象。


const symbolIsAnimal = Symbol.for("pro_symbol_attr_isAnimal");
const symbolSay = Symbol.for("pro_symbol_method_say");
const symbolSalary = Symbol.for("ins_symbol_attr_salary");
function Person(age, name){
    this.ins_in_attr_age = age;
    this.ins_in_attr_name = name;
    this.ins_in_method_walk = function () {
        console.log("ins_method_walk");
    }
}
// 原型方法
Person.prototype.pro_method_say = function(words){
    console.log("pro_method_say:", words);
}
Person.prototype[symbolSay] = function(words){
    console.log("pro_symbol_method_say", words);
}
// 原型属性
Person.prototype[symbolIsAnimal] = true;
Person.prototype.pro_attr_isAnimal = true;
const person = new Person(100, "程序员");
    //Symbol 属性
person[symbolSalary] = 6000;
person["ins_no_enumerable_attr_sex"] = "男";
// sex 不可枚举
Object.defineProperty(person, "ins_no_enumerable_attr_sex", {
    enumerable: false
});
Object.defineProperty(person, symbolSalary, {
    enumerable: false, // 无效的设置 
    value: 999
});
复制代码


我们来归类下,这些都属于哪些属性分类。


了解属性分类以后,让我们再想想 我们又如何获取person 对象的所有属性呢??


遍历对象的属性



1. for in


for(let i in person){
    console.log("for in===",i);
}
// for in=== ins_in_attr_age
// for in=== ins_in_attr_name
// for in=== ins_in_method_walk
// for in=== pro_method_say
// for in=== pro_attr_isAnimal
复制代码


可遍历原型上的属性键以及普通属性键,不可枚举的属性和Symbol属性除外。


2. Object.keys


const keys=Object.keys(person);
console.log("Object.keys==",keys)
// Object.keys== [ 'ins_in_attr_age', 'ins_in_attr_name', 'ins_in_method_walk' ]Object.keys== [ 'age', 'name', 'walk' ]
复制代码


返回的是所有可枚举属性键,也就是属性下的enumerable: true。但不包括Symbol值作为名称的属性键。


3. Object.getOwnPropertyNames


const names=Object.getOwnPropertyNames(person);
console.log("Object.getOwnPropertyNames==",names);
//
// Object.getOwnPropertyNames== [
//  'ins_in_attr_age',
//  'ins_in_attr_name',
//  'ins_in_method_walk',
//  'ins_no_enumerable_attr_sex'
// ]
复制代码


返回对象所有普通属性键 ,包括不可枚举属性但不包括Symbol值作为名称的属性键和原型属性。


4. Object.getOwnPropertySymbols


//Symbol 属性
person[symbolSalary] = 6000;
Object.defineProperty(person, symbolSalary, {
    enumerable: false, // 无效的设置 
    value: 999
});
const keys=Object.getOwnPropertySymbols(person);
console.log("Object.getOwnPropertySymbols==",keys);
console.log("描述符是否生效==",person[symbolSalary])
// Object.getOwnPropertySymbols== [ Symbol(ins_symbol_attr_salary) ]
// 描述符是否生效== 999
复制代码


返回一个给定对象自身的所有 Symbol 属性键的数组。包括不可枚举的Symbol属性。只限Symbol。


5. Reflect.ownKeys


const names=Reflect.ownKeys(person);
console.log("Object.getOwnPropertySymbols==",names);
// Reflect.ownKeys== [
//  'ins_in_attr_age',
//  'ins_in_attr_name',
//  'ins_in_method_walk',
//  'ins_no_enumerable_attr_sex',
//   Symbol(ins_symbol_attr_salary)
// ]
复制代码


返回一个由目标对象自身的属性键组成的数组。等同于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))。


6. for of


for...of 循环仅适用于可迭代的对象。 而普通对象不可迭代。在 ES6 中引入的 for...of 循环,以替代 for...in 和 forEach() ,并支持新的迭代协议。for...of 允许你遍历 Arrays(数组), Strings(字符串), Maps(映射), Sets(集合)等可迭代的数据结构等。


const obj = { fname: 'foo', lname: 'bar' };
for (const value of obj) { // TypeError: obj[Symbol.iterator] is not a function
    console.log(value);
}
复制代码
const array = ['foo', 'bar', 'baz'];
// sex 不可枚举
Object.defineProperty(array, "0", {
    enumerable: false,
    writable:false
});
array[0]="apple";
for(let i of array){
    console.log("for of===",i);
}
console.log("=====分割=========");
for(let i in array){
    console.log("for in===",i);
}
// for of=== foo
// for of=== bar
// for of=== baz
// =====分割=========
// for in=== 1
// for in=== 2
复制代码


我们通过对比for in 可以很清楚的看到 0 索引的不可枚举属性已经生效。

可遍历普通属性值,包含不可枚举属性值,不能遍历原型上的值。


总结



方法名 普通属性 不可枚举属性 Symbol属性 原型属性
for in
Object.keys
Object.getOwnPropertyNames
Object.getOwnPropertySymbols ✔(Symbol)
Reflect.ownKeys
  1. for of 获得的是属性值,不是属性键
  2. 能遍历到原型属性的只有 for in
  3. Reflect.ownKeys 综合来看是最强大的
  4. for of一般不能遍历对象,,如果实现了Symbol.iterator,可以遍历。 如Array,Map,Set,String,TypedArray,arguments 对象等等


综合来看Relect.ownKeys功能强大,能取到Symbol和普通属性,不可枚举的属性也能获取。 但属性复制的时候经常采用的是for in+ Object.hasOwnProperty 双层判断。


写在最后



不忘初衷,有所得,而不为所累,如果你觉得不错,你的一赞一评就是我前行的最大动力。


技术交流群请到 这里来。 或者添加我的微信 dirge-cloud,一起学习。

相关文章
|
3月前
|
前端开发 Java
java前端:删除数组中指定元素的方法
java前端:删除数组中指定元素的方法
|
3月前
|
JavaScript 小程序
遍历类数组之获取多个dom节点并遍历
遍历类数组之获取多个dom节点并遍历
|
4月前
各种遍历方法以及注意点
各种遍历方法以及注意点
19 0
|
9月前
根据数组中对象的属性值进行排序
根据数组中对象的属性值进行排序
64 0
|
10月前
|
索引
数组属性
数组属性
42 0
lodash遍历分配对象的属性,忽略相同属性的值
lodash遍历分配对象的属性,忽略相同属性的值
62 0
lodash反向遍历对象自身的属性
lodash反向遍历对象自身的属性
47 0
lodash反向遍历对象属性
lodash反向遍历对象属性
65 0
v-for遍历对象、数组
v-for遍历对象、数组
100 0