1. Object.assign()
通过复制一个或多个对象来创建一个新的对象。
1. Object.assign()接口可以接收多个参数,第一个参数是目标对象,后面的都是源对象,assign 方法将多个原对象的属性和方法都合并到了目标对象上面,如果在这个过程中出现同名的属性(方法),后合并的属性(方法)会覆盖之前的同名属性(方法)。
2. Object.assign()它接收的第一个参数(目标)应该是对象,如果不是对象的话,它会在内部转换成对象,所以如果碰到了 null 或者 undefined 这种不能转换成对象的值的话,assign 就会报错。但是如果源对象的参数位置,接收到了无法转换为对象的参数的话,会忽略这个源对象参数。
3. Object.assign 拷贝的属性是有限制的,只会拷贝对象本身的属性(不会拷贝继承属性),也不会拷贝不可枚举的属性。但是属性名为 Symbol 值的属性,是可以被 Object.assign 拷贝的。
let obj1 = {
name: "wang",
};
let obj2 = {
name: "xixi",
age: 18,
};
let res = Object.assign({}, obj1, obj2);
console.log(res); // {name: xixi, age: 18}
2. Object.create()
使用指定的原型对象和属性创建一个新对象。
// 接收两个参数,
// 第一个参数:新创建对象的原型对象(即新对象原型指向这个对象参数),这个同Object.defineProperty()方法的第三个参数
// 第二个参数::新对象指定的属性,是一个对象形式的配置
// value: 属性的默认值, 默认为undefined
// congigurable: 能否使用delete、能否修改属性特性、或能否修改访问器属性、false为不可重新定义,默认值为true
// enumberable: 可枚举性,对象属性能否通过for-in 循环,默认为true
// writable: 对象属性是否可修改,默认为true,可修改,设置false可理解为常量不可修改
let newObj = Object.create(
{ name: "sun" },
{
age: {
value: 24, // 属性默认值
congigurable: false, // 设置false之后将不能不删除
enumerable: true,
writable: false, // 设置false之后将不能修改
},
}
);
3. Object.defineProperty()
给对象添加一个属性并指定该属性的配置。
// 该函数接收三个参数:
// 1. object 对象 => 需要修改的对象
// 2. propName 属性名 => 需要修改的属性名称
// 3. descriptor 属性描述 => 加的这个属性的具体配置
let obj = {
name: "小张",
age: 18,
};
var count = 10;
Object.defineProperty(obj, "height", {
value: 180,
// 第一个属性value,就是给属性设置值,值可以为任意数据类型
writable: false,
// 第二个属性writable,是否可以更改, 默认为flse
enumerable: true,
// 第三个属性enumerable,是否可被枚举,
// 简单理解就是是否可被遍历出来,默认为false
configurable: true,
// 第四个属性,configurable是否可被删除或者重新定义
// 默认为false
get: function () {
return count;
},
// get 是获取值的时候的方法,类型为 function ,
// 获取值的时候会被调用,不设置时为 undefined
set: function () {
return count + 1;
},
// set 是设置值的时候的方法,类型为 function ,
// 设置值的时候会被调用,undefined
// 说明 注意:当使用了getter或setter方法,
// 不允许使用writable和value这两个属性(如果使用,会直接报错滴)
// get或set不是必须成对出现,任写其一就可以
});
obj.height = "190";
4. Object.defineProperties()
给对象添加多个属性并分别指定它们的配置。
// 接收两个参数:
// 1. 将要被添加属性或修改属性的对象
// 2. 该对象的一个或多个键值对定义了将要添加或修改的属性的具体配置(配置项和Object.defineProperty()第三个参数配置对象相同)
// 用法除了格式基本与Object.defineProperty相同
var person = {};
Object.defineProperties(person, {
name: {
value: "Jake",
configurable: true,
},
age: {
get: function () {
return this.value || 22;
},
set: function (value) {
this.value = value;
},
},
});
console.log(person.name); // Jake
console.log(person.age); // 22
5. Object.entries()
返回给定对象自身可枚举属性的[key, value]数组。
const obj = { name: "xiaoming", age: "seven" };
const res = Object.entries(obj);
console.log(res); // 结果: [['name', 'xiaoming'], ['age', 'seven']]
6. Object.is()
比较两个值是否相同
Object.is("foo", "foo"); // true
Object.is(window, window); // true
Object.is([], []); // false
// 此方法的比较类似于 ‘===’ 但是还有一些不同之处,比如:
+0 === -0; //true
NaN === NaN; // false
Object.is(+0, -0); // false
Object.is(NaN, NaN); // true
7. Object.keys()
返回一个包含所有给定对象自身可枚举属性名称的数组。
Object keys()处理对象数据时:返回可枚举的属性数组
let obj = {
name: "张",
age: 16,
sex: "nan",
};
console.log(Object.keys(obj)); //打印结果为 [name , age , sex]
Object.keys(obj).forEach((key) => {
console.log(key); //打印结果为 name , age , sex
console.log(obj[key]); //打印结果为 张 , 16 ,nan
});
Object keys()处理数组数据时:返回索引值数组
let arr = [1, 4, 2, 5];
console.log(Object.keys(arr)); //打印结果为 [0,1,2,3]
Object.keys(arr).forEach((item) => {
console.log(item); //打印结果为 0,1,2,3
console.log(arr[item]); //打印结果为 1,4,2,5
});
Object keys()处理字符串数据时:返回索引值数组
let arr = "qa12";
console.log(Object.keys(arr)); //打印结果为 [0,1,2,3]
Object.keys(arr).forEach((item) => {
console.log(item); //打印结果为 0, 1, 2, 3
console.log(arr[item]); //打印结果为 q , a , 1 , 2
});
8. Object.values()
返回给定对象自身可枚举值的数组。
Object.values()处理对象数据时:返回可枚举的值组成的数组
let obj = {
name: "张",
age: 16,
sex: "nan",
};
console.log(Object.values(obj)); //打印结果为 [张,16,nan]
Object.values(obj).forEach((key) => {
console.log(key); //张,16,nan
});
Object.values()处理数组数据时:返回原数组
let arr = [1, 4, 2, 5];
console.log(Object.values(arr)); //打印结果为 [1,4,2,5]
Object.values(arr).forEach((item) => {
console.log(item); //打印结果为 1,4,2,5
});
Object.values()处理字符串数据时:返回每个字符组成的数组
let arr = "qa12";
console.log(Object.values(arr)); //打印结果为 [q,a,1,2]
Object.values(arr).forEach((item) => {
console.log(item); //打印结果为 q,a,1,2
});
9. Object.hasOwnProperty()
用于检测一个对象是否含有特定的自身属性(非继承),返回一个布尔值
const obj = {
name: "张三",
};
obj.age = 18;
console.log(obj.hasOwnProperty("name")); // true
console.log(obj.hasOwnProperty("age")); // true
console.log(obj.hasOwnProperty("address")); // false
// 集成的属性无法检测到
function Animal(name) {}
Animal.prototype.eat = function () {
console.log("小狗在吃饭...");
};
var animal = new Animal("小狗");
console.log(animal.hasOwnProperty("eat")); // false
10. Object.isPrototypeOf()
用来判断要检查其原型链的对象是否存在于指定对象实例中
const Animal = {
isAnimal: true,
};
const Mammal = Object.create(Animal);
Mammal.isMammal = true;
Animal.isPrototypeOf(Mammal); //true
const dog = Object.create(Animal);
Object.setPrototypeOf(dog, Mammal);
Animal.isPrototypeOf(dog); //true
Mammal.isPrototypeOf(dog); //true
11. Object.getOwnPropertyDescriptor()
获取某个属性的描述对象
let obj = {
id: 1,
name: "test",
get gender() {
console.log("gender");
},
set grade(g) {
console.log(g);
},
};
Object.getOwnPropertyDescriptors(obj);
//输出结果为:
/*{
gender: {
configurable: true,
enumerable: true,
get: f gender(),
set: undefined
},
grade: {
configurable: true,
enumerable: true,
get: undefined,
set: f grade(g)
},
id: {
configurable: true,
enumerable: true,
value: 1,
writable: true
},
name: {
configurable: true,
enumerable: true,
value: 'test',
writable: true
}
}*/
// 方法还提供了第二个参数,用来获取指定属性的属性描述符
let obj = {
id: 1,
name: "test",
};
Object.getOwnPropertyDescriptors(obj, "id");
//输出结果为:
/*{
id: {
configurable: true,
enumerable: true,
value: 1,
writable: true
}
}*/
12. Object.getOwnPropertyNames()
遍历对象的属性,包括不可枚举的属性。 但不考虑继承的属性。
const dog = {};
dog.breed = "Siberian Husky";
dog.name = "Roger";
Object.getOwnPropertyNames(dog); //[ 'breed', 'name' ]
13. Object.preventExtensions()
防止对象扩展
let people = {
name: "quanyi",
position: "developer",
age: 18,
};
Object.preventExtensions(people);
people.age = 12; // 可以修改
delete people.position; // 可以删除
// people.aa = "aa"; // 报错 "TypeError: Cannot add property aa, object is not extensible"
14. Object.isExtensible()
判断对象是否可扩展
任何对象都是可扩展的,除非已将其用作:
1. Object.freeze()
2. Object.seal()
3. Object.preventExtensions()
const dog = {};
Object.isExtensible(dog); //true
const cat = {};
Object.freeze(cat);
Object.isExtensible(cat); //false
15. Object.seal()
禁止对象配置,对象上的所有属性的 configurable 都设置成 false
const seal = Object.seal({ name: "O.O" });
seal.name = "D.O"; // seal { name: 'D.O' } 可以修改
delete seal.name; // freeze { name: 'O.O' } 不可删除
seal.age = 18; // seal { name: 'O.O' } 不可新增
16. Object.isSealed()
判断一个对象是否可配置
const dog = {};
dog.breed = "Siberian Husky";
const myDog = Object.seal(dog);
Object.isSealed(dog); //true
Object.isSealed(myDog); //true
dog === myDog; //true
17. Object.freeze()
冻结一个对象
var obj = {
name: "张三",
age: 18,
address: "上海市",
};
obj.__proto__.habit = "运动";
// 冻结对象
Object.freeze(obj);
// 不能添加新属性
obj.sex = "男";
console.log(obj); // {name: "张三", age: 18, address: "上海市"}
// 不能删除原有属性
delete obj.age;
console.log(obj); // {name: "张三", age: 18, address: "上海市"}
// 不能修改已有属性的值
obj.name = "李四";
console.log(obj); // {name: "张三", age: 18, address: "上海市"}
// 不能修改原型
obj.__proto__ = "随便什么值";
console.log(obj.__proto__); // {habit: "运动", constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, …}
// 不能修改已有属性的可枚举性、可配置性、可写性
Object.defineProperty(obj, "address", {
// TypeError: Cannot redefine property: address
enumerable: false,
configurable: false,
writable: true,
});
18. Object.isFrozen()
判断一个对象是否被冻结
const obj = {
name: "xixi",
};
Object.freeze(obj);
console.log(Object.isFrozen(obj));
19. Object.prototype.valueOf()
返回一个对象的“值”,默认情况下返回对象本身。主要用途是,JavaScript 自动类型转换时会默认调用这个方法
类型 | 示例 | 结果 |
---|---|---|
Array | [1,2,3].valueOf() | [1, 2, 3] |
Boolean | false.valueOf() | false |
Date | new Date().valueOf() | 1680917450492(时间戳) |
Function | let a = function() {} a.valueOf() | ƒ () {} |
Number | let a = 1 a.valueOf() | 1 |
Object | let a = {} a.valueOf() | {} |
String | "abc".valueOf() | 'abc' |
20. Object.prototype.toString()
通过自定义 toString 方法,可以让对象在自动类型转换时,得到想要的字符串形式。
类型 | 示例 | 结果 |
---|---|---|
Array | [1,2,3].toString() | "1, 2, 3" |
Boolean | false.toString() | "false" |
Date | new Date().toString() | 'Sat Apr 08 2023 09:20:38 GMT+0800 (中国标准时间)' |
Function | let a = function() {} a.toString() | 'function() {}' |
Number | let a = 1 a.toString() | '1' |
Object | let a = {} a.toString() | '[object Object]' |
String | "abc".toString() | 'abc' |
valueOf()和 toString()方法小结
1. valueOf()偏向于运算,toString()偏向于显示
2. 对象转换时,优先调用 toString()
3. 强转字符串的情况下,优先调用 toString()方法;强转数字的情况下优先调用 valueOf()
4. 正常情况下,优先调用 toString()
5. 在有运算操作符的情况下 valueOf()的优先级高于 toString(),这里需要注意的是当调用 valueOf()方法无法运算后还是会再调用 toString()方法