Javascript对象中常用的方法

142 阅读7分钟

Javascript对象中常用的方法.png

常用的方法

Object.keys()

Object.keys()  方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致

语法

Object.keys(obj)

参数: obj要返回其枚举自身属性的对象
返回值:一个表示给定对象的所有可枚举属性的字符串数组
描述:Object.keys返回一个所有元素为字符串的数组,其元素来自于从给定的`object`上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致

注意

  • 只关注对象的自身可枚举属性键,原型对象继承的属性会跳过

例子

// 简单数组
var arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // console: ['0', '1', '2']

// 对象1
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // console: ['0', '1', '2']

// 对象2
var anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj)); // console: ['2', '7', '100']

// 对象3
var myObj = Object.create({}, {
  getFoo: {
    value: function () { return this.foo; }
  }
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: ['foo']

如果你想获取一个对象的所有属性,,甚至包括不可枚举的,请查看Object.getOwnPropertyNames

Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有Symbol属性的数组

Object.values()

Object.values() 方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )

语法

Object.values(obj)

参数:obj被返回可枚举属性值的对象
返回值:一个包含对象自身的所有可枚举属性值的数组
描述:Object.values()返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同

例子

var obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']

Object.entries()

Object.entries() 方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)

语法

Object.entries(obj)

参数:obj可以返回其可枚举属性的键值对的对象
返回值:给定对象自身可枚举属性的键值对数组
描述:`Object.entries()`返回一个数组,其元素是与直接在`object`上找到的可枚举属性键值对相对应的数组。属性的顺序与通过手动循环对象的属性值所给出的顺序相同

例子

const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]


const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]


const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

应用场景

将Object转换为Map new Map()构造函数接受一个可迭代的entries。借助Object.entries方法你可以很容易的将Object转换为Map

var obj = { foo: "bar", baz: 42 };
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }
map.get('foo') // "bar"
map.get('baz') // 42

Object.assign()

Object.assign()  方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象

语法

Object.assign(target, ...sources)

参数:target目标对象 source源对象
返回值:目标对象
描述:如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性

注意

  • Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()Object.defineProperty()String类型和 Symbol 类型的属性都会被拷贝。
  • 针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是(可枚举)属性值,假如源值是一个对象的引用,它仅仅会复制其引用值。
  • 继承属性和不可枚举属性是不能拷贝的。
const obj = Object.create({foo: 1}, { // foo 是个继承属性。
    bar: {
        value: 2  // bar 是个不可枚举属性。
    },
    baz: {
        value: 3,
        enumerable: true  // baz 是个自身可枚举属性。
    }
});

const copy = Object.assign({}, obj);
console.log(copy); // { baz: 3 }

例子

const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

Object.prototype.hasOwnProperty()

hasOwnProperty()  方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)

语法

obj.hasOwnProperty(prop)

参数:obj要检测的属性的String字符串形式表示的名称,或者Symbol
返回值:用来判断某个对象是否含有指定的属性的布尔值Boolean
描述:所有继承了Object的对象都会继承到hasOwnProperty方法。这个方法可以用来检测一个对象是否含有特定的自身属性;和in运算符不同,该方法会忽略掉那些从原型链上继承到的属性
备注:即使属性的值是nullundefined,只要属性存在,hasOwnProperty依旧会返回true

例子

o = new Object();
o.propOne = null;
o.hasOwnProperty('propOne'); // 返回 true
o.propTwo = undefined;
o.hasOwnProperty('propTwo'); // 返回 true

o = new Object();
o.hasOwnProperty('prop'); // 返回 false
o.prop = 'exists';
o.hasOwnProperty('prop'); // 返回 true
delete o.prop;
o.hasOwnProperty('prop'); // 返回 false

注意

  • for..in不仅可以循环枚举自身属性还可以枚举原型链中的属性

Object.create()

Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

语法

Object.create(proto,[propertiesObject])

参数:proto新创建对象的原型对象,propertiesObject可选。需要传入一个对象,该对象的属性类型参照Object.defineProperties()的第二个参数。如果该参数被指定且不为undefined,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符
返回值:一个新对象,带着指定的原型对象和属性

例子

const obj = {
    name: "nordon",
};

const newObj = Object.create(obj);
const newObj2 = Object(obj);

注意

  • 字面量和new关键字创建的对象是Object的实例,原型指向Object.prototype,继承内置对象Object

  • Object.create(arg, pro)创建的对象的原型取决于argargnull,新对象是空对象,没有原型,不继承任何对象;arg为指定对象,新对象的原型指向指定对象,继承指定对象

Object.getPrototypeOf()

Object.getPrototypeOf()  方法返回指定对象的原型(内部[[Prototype]]属性的值)

语法

Object.getPrototypeOf(object)

参数:要返回其原型的对象
返回值:给定对象的原型。如果没有继承属性,则返回null

例子

var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true

var reg = /a/;
Object.getPrototypeOf(reg) === RegExp.prototype; // true

判断JS对象为空的几种方法

可枚举或者不可枚举属性是对象内部通过可枚举标志enumerable来进行区分的,在默认情况下,我们为对象新增了一个属性后,其可枚举标志enumerableture,而当其值为false的时候它是不可枚举的,当对对象进行for,Object.keys(),JSON.stringify()时不可枚举属性是找不出来的,即可理解为不可枚举属性是隐身的。

  1. JSON.stringify判断,不过不推荐使用,效率不高且只能用于可转化成字符串的属性。如果是undefined是有问题了
let obj = {
    name: "xxx"
}
console.log(JSON.stringify(obj) == '{}')
  1. for in

当触发循环时返回false没有触发循环时代表对象为空返回ture

let isNull = (obj) => {
    for (let key in obj) {
        return false
    }
    return true
}

  1. Object.getOwnPropertyNames

Object.getOwnPropertyNames,将返回的数组的length作为判断依据

let arr = Object.getOwnPropertyNames(obj)
console.log(arr.length === 0)
  1. Object.keys() 和Object.getOwnPropertyNames判断类似
let arr = Object.keys(obj)
console.log(arr.length === 0)
  1. hasOwnProperty

hasOwnProperty是使用for循环将元素进行判断如果含有则返回false说明不为空,反之则为空

let isNull = (obj) => {
    for (let key in obj) {
        if(obj.hasOwnProperty(key)){
            return false
        }
    }
    return true
}

注意:

  • 若Symbol为对象的key的属性时用getOwnPropertySymbols

总结

  • Object.values() 和Object.entries() 为JS开发人员提供了很大的方便
  • Object.entries()适用于数组解构赋值,其方式是将键和值轻松分配给不同的变量。 此函数还可以轻松地将纯JS对象属性映射到Map对象中
  • Object.values()Object.entries()返回数据的顺序是不确定的,所以不要依赖该方式
  • 对象属性的顺序
数字:当属性的类型时数字类型时,会按照数字的从大到小的顺序进行排序;
字符串:当属性的类型是字符串时,会按照时间的先后顺序进行排序;
Symbol:当属性的类型是Symbol时,会按照时间的先后顺序进行排序

如果需要有序集合,建议将数据存储到数组或`Set`