JavaScript 中对象属性与方法汇总

Javascript 中对象属性与方法汇总

1. Object 构造函数的方法

需要通过构造函数调用,如 Object.keys()

1. Object.assign()

用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,并返回目标对象

const obj = {
    name: 'obj name'
};

const copy = Object.assign(obj, {
    a: 'aaa'
});

console.log(copy === obj);

// 更多的时候用来合并对象

const a = {
    name: 'name a'
};

Object.defineProperty(a, 'b', {
    value: 'prop b',
    enumerable: false // 不可枚举
});

const b = {
    name: 'name b',
    type: 'object'
};

const copy = Object.assign({}, a, b);

console.log(copy); // { name: 'name b', type: 'object' } 相同的属性会被覆盖
console.log(a.b); // prop b
console.log(copy.b); // undefined 继承属性和不可枚举属性的属性不能拷贝
2. Object.create()

使用指定的原型对象及一些属性去创建一个新的对象,第二个参数是一个新添加属性的描述符集合,与 Object.defineProperties() 第二个参数类似

const proto = {
    name: 'proto name'
};

const a = Object.create(proto, {
    // getName 会成为 创建对象的属性
    getName: {
        // 值为一个属性描述符
        value: function() {
            return this.name;
        }
    }
});

console.log(a.getName());

// 创建一个原型为 null 的空对象
const b = Object.create(null);

console.log(b);
3. Object.defineProperty()

在一个对象上定义一个新的属性,或者修改一个对象的现有属性,并返回对象,允许精确添加或修改对象的属性

const obj = {
    a: 'number is 1.32'
};
// 给 obj 对象上定义 ‘b’ 属性
Object.defineProperty(obj, 'b', {
    value: 'default value', // 该属性对应的值,可以是任意类型
    writable: true, // 是否可写,true 表示可以被运算符改变
    enumerable: true, // 是否可枚举,可枚举的属性才可以被 in 运算符检查和被 Object.keys() 返回
    configurable: false // 目前定义的描述符是否是可以修改的, 设置为 true 不但可以被修改,此属性也可以被删除
});
4. Object.defineProperties()

在一个对象上定义新的属性或修改现有属性,并返回该对象,与 defineProperty 区别是可以定义多个属性

const obj = {
    name: 'obj name'
};

Object.defineProperties(obj, {
    getName: {
        value: function() {
            return this.name;
        }
    },
    changeName: {
        value: function(name) {
            this.name = name;
        }
    }
});

console.log(obj.getName()); // obj name
obj.changeName('xxx');
console.log(obj.getName()); // xxx
5. Object.freeze() Object.isFrozen()

Object.freeze() 用于冻结一个对象,冻结后,不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,包括其已有属性的描述符都不能修改,该方法会返回被冻结对象

Object.isFrozen() 判断是否已冻结

const child = {
    id: 'child id'
};

const obj = {
    name: 'obj name',
    child: child
};

console.log(obj); // { name: 'obj name', child: { id: 'child id' } }

// 冻结
const freeze = Object.freeze(obj);
console.log(Object.isFrozen(obj)); // true 判断是否冻结

console.log(freeze === obj); // true
// 尝试改变属性
obj.name = 'new name';
console.log(obj.name); // obj name 没有改变

// 尝试添加
obj.newProp = 'new prop';
console.log(obj.newProp); // undefined 添加失败

// 更改属性中的对象内容,但指针地址不变
child.id = 'new id';
console.log(obj.child); // { id: 'new id' } 可以改变
6. Object.preventExtensions() Object.isExtensible()

Object.preventExtensions() 使得一个对象变得不可扩展,不能添加新属性

Object.isExtensible() 判断是否是不可扩展的对象

const a = {
    name: 'a'
};

// 使不可扩展
Object.preventExtensions(a);
console.log(Object.isExtensible()); // false 不可扩展

// 尝试添加新属性
a.type = 'type';
console.log(a.type); // undefined 不可以添加新属性

// 尝试更改原属性
a.name = 'new name';
console.log(a.name); // new name 可以更改原属性
7. Object.seal() Object.isSealed()

Object.seal() 让一个对象密封,并返回被密封后的对象。密封对象将会阻止向对象添加新的属性,并且会将所有已有属性的可配置性(configurable)置为不可配置(false),即不可修改属性的描述或删除属性。但是可写性描述(writable)为可写(true)的属性的值仍然可以被修改。

Object.isSealed() 判断是否是密封的

// MDN 上的例子
const obj = {
    prop: function() {},
    foo: 'bar'
};

// 可以添加新的属性,已有属性的值可以修改,可以删除
obj.foo = 'baz';
obj.lumpy = 'woof';
delete obj.prop;

const o = Object.seal(obj);

console.log(o === obj); // true
console.log(Object.isSealed(obj) === true); // true

// 仍然可以修改密封对象上的属性的值.
obj.foo = 'quux';

// 但你不能把一个数据属性重定义成访问器属性.
Object.defineProperty(obj, 'foo', {
    get: function() {
        return 'g';
    }
}); // 抛出TypeError异常

// 现在,任何属性值以外的修改操作都会失败.
obj.quaxxor = 'the friendly duck'; // 静默失败,新属性没有成功添加
delete obj.foo; // 静默失败,属性没有删除成功
8. Object.is()

判断两个值是否相等,与传统的判断方法 == === 不太一样

const a = {
    name: 'a'
};

const b = {
    name: 'a'
};

Object.is(a, b); // false
Object.is([], []); // false
Object.is(null, null); // true
Object.is(0, -0); // false
Object.is(NaN, NaN); // true
9. Object.getOwnPropertyDescriptor()

返回指定对象上一个自有属性的描述符

const proto = {
    protoName: 'proto name'
};

const obj = Object.create(proto, {
    name: {
        value: 'obj name'
    }
});

console.log(Object.getOwnPropertyDescriptor(obj, 'name'));
/*
   {
      value: 'obj name',
      writable: false,
      enumerable: false,
      configurable: false
   }
*/
console.log(obj.protoName); // proto name 可以获取到
console.log(Object.getOwnPropertyDescriptor(obj, 'protoName')); // undefined 不能得到原型链上的属性
10. Object.getPrototypeOf()

返回指定对象的原型

const proto = {
    protoName: 'proto name'
};

const obj = Object.create(proto, {
    name: {
        value: 'obj name'
    }
});

console.log(Object.getPrototypeOf(obj) === proto); // true
11. Object.keys()

返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)。

const proto = {
    protoName: 'proto name'
};

const obj = Object.create(proto, {
    name: {
        value: 'obj name',
        enumerable: true // 设置为可枚举,否则遍历不到
    },
    age: {
        value: 'obj age',
        enumerable: false // 设置为不可枚举,这样不会被遍历到
    }
});

let arr = [];

for (const key in obj) {
    arr.push(key);
}

console.log(arr); // [ 'name', 'protoName' ] for-in 循环会遍历原型链上的可枚举属性
console.log(Object.keys(obj)); // [ 'name' ] Object.keys() 只返回自身的可枚举属性
12. Object.values()

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

const proto = {
    protoName: 'proto name'
};

const obj = Object.create(proto, {
    name: {
        value: 'obj name',
        enumerable: true // 设置为可枚举,否则遍历不到
    },
    age: {
        value: 'obj age',
        enumerable: false // 设置为不可枚举,这样不会被遍历到
    }
});

console.log(Object.values(obj));
/*
   [ 'obj name' ]
   Object.values() 只返回自身的可枚举属性的值
   不可枚举的与原型链上的属性都没有返回
*/
13. Object.entries()

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

const proto = {
    protoName: 'proto name'
};

const obj = Object.create(proto, {
    name: {
        value: 'obj name',
        enumerable: true // 设置为可枚举,否则遍历不到
    },
    age: {
        value: 'obj age',
        enumerable: false // 设置为不可枚举,这样不会被遍历到
    }
});

console.log(Object.entries(obj));
/*
   [ [ 'name', 'obj name' ] ]
   Object.entries() 只返回自身的可枚举属性的键值对
   不可枚举的与原型链上的属性都没有返回
*/
14. Object.getOwnPropertyNames()

返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括 Symbol 值作为名称的属性)组成的数组

const proto = {
    protoName: 'proto name'
};

const obj = Object.create(proto, {
    name: {
        value: 'obj name',
        enumerable: true // 设置为可枚举,否则遍历不到
    },
    age: {
        value: 'obj age',
        enumerable: false // 设置为不可枚举,这样不会被遍历到
    }
});

const key = Symbol('key');
obj[key] = 'symbol value';

console.log(Object.getOwnPropertyNames(obj));
/*
   [ 'name', 'age' ]
   Object.getOwnPropertyNames() 只返回自身的属性名集合
   包括不可枚举的属性,但是不包括 Symbol 类型的属性名
*/
14. Object.getOwnPropertySymbols()

返回一个给定对象自身的所有 Symbol 属性的数组

const proto = {
    protoName: 'proto name'
};

const obj = Object.create(proto, {
    name: {
        value: 'obj name',
        enumerable: true
    }
});

const key = Symbol('key');
obj[key] = 'symbol value';
const symbols = Object.getOwnPropertySymbols(obj);

console.log(symbols); // [ Symbol(key) ]
symbols.forEach(symbol => console.log(symbol.constructor)); // [Function: Symbol]

2. Object.prototype Object 原型对象(或者对象实例)上的属性与方法

几乎所有的 JavaScript 对象都是 Object 的实例,一个典型的对象会继承 Object.prototype 的属性和方法

1. .constructor

返回创建实例对象的构造函数的引用

const o = {};
o.constructor === Object; // true
const a = [];
a.constructor === Array; // true
const num = 20;
num.constructor === Number; // true
2. .hasOwnProperty()

返回一个布尔值,指示对象自身是否具有指定的属性

const obj = {
    getVal() {
        return this.val;
    }
};
obj.__proto__.val = 'prototype val';

Object.defineProperty(obj, 'b', {
    value: 'bbb',
    enumerable: false // 一个不可枚举属性
});

console.log(obj);
console.log(obj.getVal()); // 'prototype val'
console.log(obj.hasOwnProperty('val')); // false
console.log(obj.hasOwnProperty('b')); // true
3. .isPrototypeOf()

用于测试一个对象是否存在于另一个对象的原型链上

const protoObj = {
    proto: 'proto obj'
};

// Object.create(proto); 表示 以 proto 为原型创建对象
const obj = Object.create(protoObj);

console.log(obj.proto); // proto obj
console.log(protoObj.isPrototypeOf(obj)); // true
4. .propertyIsEnumerable()

判断指定属性是否是可枚举的

const obj = {};

Object.defineProperty(obj, 'a', {
    enumerable: false, // 不可枚举
    value: 'aaa'
});

console.log(obj.a);
console.log(Object.prototype.propertyIsEnumerable.call(obj, 'a')); // false
5. .toString()

返回一个对象的字符串表示

const a = {
    name: 'a name'
};

function Test() {}
const b = new Test();

console.log(a.toString()); // [object Object]
console.log(b.toString()); // [object Object]

/*
   Function Array String 等类型的 toString() 方法都有被覆盖
   如果想使用 toString()检测对象类型 可以用如下的方法
*/
const arr = ['xxx', 'yyy'];
const fun = function() {};

console.log(arr.toString()); // xxx,yyy
console.log(fun.toString()); // function () {}
console.log(Object.prototype.toString.call(arr)); // [object Array]
console.log(Object.prototype.toString.call(fun)); // [object Function]
6. .toLocaleString()

同样是返回一个对象的字符串表示,但是可以用于派生对象为了特定语言环境的目的(locale-specific purposes)而重载使用。

Array\Number\Date 等内置对象都有对这个方法的覆盖,在一般 Object 中其返回的结果与 toString() 一致

const arr = [{}, 1231, function() {}, new Date()];

console.log(arr.toString()); // [object Object],1231,function () {},Sun Feb 11 2018 11:17:09 GMT+0800 (CST)
console.log(arr.toLocaleString()); // [object Object],1,231,function () {},2018-2-11 11:17:09
7. .valueOf()

返回指定对象的原始值

const obj = {
    name: 'obj name'
};
console.log(obj.valueOf()); // { name: 'obj name' }

参考

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值