Object用法总结
什么是Object?
js中对象是一组属性与方法的集合。
如何创建Object类型?
(1)方法1,使用new操作符后跟Object构造函数,如下:
var person = new Object();
person.name="jisoo";
person.age=12;
(2)使用对象字面量表示法,如下:
var person={
name:"jisoo",
age:12
}
Object.key()
读取对象的所有属性。
1.例如,传入一个对象,返回包含对象可枚举的属性
var obj = {
name: 'jisoo',
age: 12,
say: function() {
alert("Hello World");
}
}
console.log(Object.keys(obj));
打印结果:
注:Object.keys()的结果为一个数组,上面的里面还可以通过length读取属性的个数,Object.keys(obj).length输出结果为3
2.例如,传入一个字符串,返回字符串索引值
var myStr="Hello World"
console.log(Object.keys(myStr));
//打印结果为["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
3.例如,传入一个数组,返回索引值
var arr=['a','b','c'];
console.log(Object.keys(arr));
//结果为['0','1','2']
4.例如,构造函数,返回空数组或者属性名
function Demo(name, age) {
this.name = name;
this.age = age;
}
console.log(Object.keys(Demo));
//结果为[]是一个空数组
Object.values()
方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for…in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
语法:
Object.values(obj)
参数: obj:被返回可枚举属性值的对象。 返回值: 一个包含对象自身的所有可枚举属性值的数组。 描述: Object.values()返回一个数组,其元素是在对象上找到的可枚举属性值。属性的顺序与通过手动循环对象的属性值所给出的顺序相同。
如下例子:
var obj = {
name: "jisoo",
color: "red",
age: 12
};
console.log(Object.values(obj));//结果为["lisa", "red", 12]
Object.defineProperties()
功能: 方法直接在一个对象上定义一个或多个新的属性或修改现有属性,并返回该对象。
语法: Object.defineProperties(obj, props)
参数说明:
obj: 将要被添加属性或修改属性的对象
props: 该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
var obj = new Object();
Object.defineProperties(obj, {
name: {
value: '张三',
configurable: false,
writable: true,
enumerable: true
},
age: {
value: 18,
configurable: true
}
})
console.log(obj.name, obj.age) // 张三, 18
Object.create()
生成实例对象的常用方法,使用new命令让构造函数返回一个实例,但是很多时候,只能拿到一个实例对象,它可能根本不是由构造函数生成的,那么能不能从一个实例对象,生成另一个实例对象呢?
js提供了Object.create()方法,来满足这种需求,该方法接受一个对象作为参数,然后以它为原型,返回一个实例对象,该实例完全继承原型对象的属性。
var A = {
say: function() {
console.log("我说点啥?")
}
}
//使用A作为B的原型,此时B将会拥有A的属性和方法
var B = Object.create(A);
//判断B的原型对象是不是A
console.log(Object.getPrototypeOf(B) === A); //结果为true
//B可以直接调用A的方法
B.say(); //结果为”我说点啥?“
//判断A和B的方法是不是同一个?
console.log(B.say === A.say); //结果为true
上面代码中,Object.create方法以A对象为原型,生成了B对象,B继承了A的所有属性和方法。
使用Object.create方法的时候,必须提供对象原型,即参数不能为空,或者不是对象,否则会报错。
如下会报错: Object.create(); Object.create(123)
Object.create方法生成的新对象,动态继承了原型。在原型上添加或修改任何方法,会立刻反映在新对象之上。 例如:
var obj1 = {
p: 1
};
var obj2 = Object.create(obj1);
obj1.p = 2;//修改obj1的p属性的值
console.log(obj2.p);//打印结果为2
上面代码中,obj2继承obj1,修改obj1会影响到obj2
除了对象的原型,Object.create方法还可以接受第二个参数,该参数是一个属性描述对象,它所描述的对象属性,会添加到实例对象,作为该对象自身的属性。
var obj = Object.create({}, {
p1: {
value:123,
enumerable:true,
configurable:true,
writable:true
},
p2:{
value:'hello',
enumerable:true,
configurable:true,
writable:true
}
});
//等同于
var obj = Object.create({});
obj.p1 = 123;
obj.p2 = 'hello';
Object.create方法生成的对象,继承了它的原型对象的构造函数。
function A() {}
var a = new A();
var b = Object.create(a);
b.constructor === A // true
b instanceof A // true
上面代码中,b对象的原型是a对象,因此继承了a对象的构造函数A。
Object.assign()
该方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
语法: Object.assign(target,…sources) 参数说明: target:目标对象。 …sources:源对象。 返回值: 目标对象。
语法: Object.assign(a,b); b是源对象,a是目标对象,就是将b中的属性复制到a中,b不会被改变,a会被改变。
例子:
var a = {
name: "jisoo",
age: 12,
color: "red"
};
var c = Object.assign({ address: "beijing" }, a);
console.log(c);//结果为{address: "beijing", name: "lisa", age: 12, color: "red"}
console.log(a);//{name: "lisa", age: 12, color: "red"}
Object.assign并不会改变源对象,但是会改变目标对象,如下例子:
var a = {
name: "lisa",
age: 12,
color: "red"
};
var b={
job:"teacher"
}
var c = Object.assign(b, a);
console.log(b);//结果{job: "teacher", name: "lisa", age: 12, color: "red"}
上述例子中b的结果被改变了。 注: 如果目标对象中的属性具有相同的键,则属性将被源中的属性覆盖。后来的源的属性将类似地覆盖早先的属性。
Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。
该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。
如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。
在出现错误的情况下,例如,如果属性不可写,会引发TypeError,如果在引发错误之前添加了任何属性,则可以更改target对象。
注意,Object.assign 不会跳过那些值为 null 或 undefined 的源对象。
Object.getOwnPropertyDescriptor()
功能: 该方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性),即返回对象的属性描述。
语法: Object.getOwnPropertyDescriptor(obj, prop)
参数说明: obj: 需要查找的目标对象 prop: 目标对象内属性名称
var person = {
name: '张三',
age: 12
}
var des = Object.getOwnPropertyDescriptor(person, 'name');
console.log(des);
// 结果如下:{value: "张三", writable: true, enumerable: true, configurable: true}
Object.hasOwn()
如果指定的对象自身有指定的属性,则静态方法 Object.hasOwn() 返回 true。如果属性是继承的或者不存在,该方法返回 false。
备注: Object.hasOwn() 旨在取代 Object.prototype.hasOwnProperty()。
const object1 = {
prop: 'exists',
};
console.log(Object.hasOwn(object1, 'prop'));
// Expected output: true
console.log(Object.hasOwn(object1, 'toString'));
// Expected output: false
console.log(Object.hasOwn(object1, 'undeclaredPropertyValue'));
// Expected output: false
语法
Object.hasOwn(obj, prop)
参数
obj
要测试的 JavaScript 实例对象。
prop
要测试属性的 String 类型的名称或者 Symbol。
返回值
如果指定的对象中直接定义了指定的属性,则返回 true;否则返回 false。
描述
如果指定的属性是该对象的直接属性——Object.hasOwn() 方法返回 true,即使属性值是 null 或 undefined。如果属性是继承的或者不存在,该方法返回 false。它不像 in 运算符,这个方法不检查对象的原型链中的指定属性。
建议使用此方法替代 Object.prototype.hasOwnProperty(),因为它适用于使用 Object.create(null) 创建的对象,以及重写了继承的 hasOwnProperty() 方法的对象。尽管可以通过在外部对象上调用 Object.prototype.hasOwnProperty() 解决这些问题,但是 Object.hasOwn() 更加直观。
示例
使用 hasOwn 去测试属性是否存在
以下代码展示了如何确定 example 对象中是否包含名为 prop 的属性。
const example = {};
Object.hasOwn(example, "prop"); // false——目标对象的属性 'prop' 未被定义
example.prop = "exists";
Object.hasOwn(example, "prop"); // true——目标对象的属性 'prop' 已被定义
example.prop = null;
Object.hasOwn(example, "prop"); // true——目标对象本身的属性存在,值为 null
example.prop = undefined;
Object.hasOwn(example, "prop"); // true——目标对象本身的属性存在,值为 undefined
直接属性和继承属性 以下示例区分了直接属性和通过原型链继承的属性:
const example = {};
example.prop = "exists";
// `hasOwn` 静态方法只会对目标对象的直接属性返回 true:
Object.hasOwn(example, "prop"); // 返回 true
Object.hasOwn(example, "toString"); // 返回 false
Object.hasOwn(example, "hasOwnProperty"); // 返回 false
// `in` 运算符对目标对象的直接属性或继承属性均会返回 true:
"prop" in example; // 返回 true
"toString" in example; // 返回 true
"hasOwnProperty" in example; // 返回 true
迭代对象的属性 要迭代对象的可枚举属性,你应该这样使用:
const example = { foo: true, bar: true };
for (const name of Object.keys(example)) {
// …
}
但是如果你使用 for...in,你应该使用 Object.hasOwn() 跳过继承属性:
const example = { foo: true, bar: true };
for (const name in example) {
if (Object.hasOwn(example, name)) {
// …
}
}
检查数组索引是否存在
Array 中的元素被定义为直接属性,所以你可以使用 hasOwn() 方法去检查一个指定的索引是否存在:
const fruits = ["Apple", "Banana", "Watermelon", "Orange"];
Object.hasOwn(fruits, 3); // true ('Orange')
Object.hasOwn(fruits, 4); // false——没有定义