JavaScript Object
JS的Object到底是啥东西呢?它有啥东西呢?
我们简单知道的,就是new一个Object实例对象,那这个实例对象又何Object又有什么关系呢?
先打印一下看看
console.dir(Object);
1、prototype
为啥要先说这个呢?——原型
这prototype里面的内容就是:new出来的对象的原型链上(__proto__)的内容
另一篇文章:{}对象的原型对象
2、assign(obj1, obj2)
官方解释:将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。
理解:两个参数对象,把obj2合到obj1上,相同的属性会覆盖掉,更改obj1的内容,返回更改后的obj1。
let obj1 = {
name: 'obj1',
age: 18,
}
let obj2 = {
age: 24,
phone: 114
}
console.dir(Object.assign(obj1,obj2));
console.log(obj1);
2、create(obj)
官方解释:创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
理解:参数是个对象,创建了个新对象,新对象有个[[Prototype]],里面的内容就是参数对象,这里在结合另一篇文章:{}对象的原型对象去瞅瞅
let obj1 = {
name: 'obj1',
age: 18,
}
console.dir(Object.create(obj1));
这里我又发现了另一个问题,另一篇文章:{}对象的原型对象里的{},如果是create()出来的,那参数应该是啥????换句话说,空对象的[[Prototype]]是谁???
let {} = Object.create(?????这里应该是啥)
3、defineProperties(obj, props)
官方解释:直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
理解:定义一个对象的属性,通过设置某些值(第二个参数props里面)(或称之为描述符),使得这个对象的值具有自己的特点
第二个参数的值(描述符)有:
- value: 这个属性的值,默认undefined
- configurable:这个属性的描述符可不可以被修改和这个属性可不可以被删除,默认false
- enumerable:该属性可不可以出现在对象的枚举属性中,默认false
- writable:该属性的值(value)可不可以被修改,默认false
- get:返回该属性的值,不可与value同用,默认undefined
- set:设置该属性的值,默认undefined
就是说,默认全是false,什么情况下才会用这些东西呢?反之我是没用到过
1、基础使value
let obj = {};
Object.defineProperties(obj, {
'property0': {
value: 'Hello World', // 这个property0的值
}
});
console.log(obj);//{property0: 'Hello World'}
给obj加了个属性:property0,值为’Hello World’
2、configurable
let obj = {};
Object.defineProperties(obj, {
'property0': {
value: 'Hello World',
configurable:true,
},
'property1': {
value: true,
}
});
delete obj.property0;
delete obj.property1;
console.log(obj); // {property1: true}
属性property0可以被删除,property1不行。因为property0的configurable是true,至于文档说的可修改该属性的描述符没试
3、enumerable
let obj = {};
Object.defineProperties(obj, {
'property0': {
value: 'Hello World',
configurable:true,
enumerable:true
},
'property1': {
value: true,
},
'property2': {
value: [1,2,3],
enumerable:true
}
});
for (i in obj){
console.log(i); // property0 property2
}
property0 property2两个属性可以被枚举到(我单纯的理解能被for…in到的就是可枚举的)
4、writable
let obj = {};
Object.defineProperties(obj, {
'property0': {
value: 'Hello World',
configurable:true,
enumerable:true
},
'property1': {
value: true,
},
'property2': {
value: [1,2,3],
enumerable:true
},
'property3': {
value: "ABCDEFG",
writable:true
},
});
Object.assign(obj, {
property0:"yes", //TypeError: Cannot assign to read only property 'property0' of object
property3:'lol'
})
console.log(obj); //{property0: 'Hello World', property2: Array(3), property1: true, property3: 'lol'}
property0不能被修改,会报错的。property3可以
5、get和set
let obj = {};
let property4Get = "LOL"
Object.defineProperties(obj, {
'property0': {
value: 'Hello World',
configurable:true,
enumerable:true
},
'property1': {
value: true,
},
'property2': {
value: [1,2,3],
enumerable:true
},
'property3': {
value: "ABCDEFG",
writable:true
},
"property4":{
get(){
return "这是get方法返的" + property4Get
},
set(value){
property4Get = value
}
}
});
console.log(obj.property4); //这是get方法返的LOL
obj.property4 = "LOLOLOL"
console.log(obj.property4); //这是get方法返的LOLOLOL
不能和value同用,property4直接用和直接改就行,见上边代码
4、defineProperty(obj, prop, descriptor)
和defineProperties一样都是去新建或修改对象的属性。但defineProperty是单个的去设置属性:defineProperty(obj, “property0属性名”, {描述符})
5、entries(obj)
官方解释:返回一个给定对象自身可枚举属性的键值对数组
理解:把对象的属性和值分解成一个二维数组,每一项的数组里有两个值,一个key,一个value
let obj = {
name:'obj',
age:18,
eat: function(){},
'3': "three",
'1': 'one'
}
console.log(Object.entries(obj));
PS:它有一个自己的排序规则吧。
然后,如同参数是一个字符串,会把字符串也分解成二维数组
然后分解的结果还可用for of或者forEach或者map进行“键值”遍历
console.log(Object.entries('obj'));
/*
(3) [Array(2), Array(2), Array(2)]
0: (2) ['0', 'o']
1: (2) ['1', 'b']
2: (2) ['2', 'j']
*/
let obj = Object.entries('obj')
for (const [key, value] of obj){
console.log("for..of:"+key+':'+value);
}
obj.forEach(([key,value]) => {
console.log("foreach:"+key+':'+value);
});
obj.map(([key,value])=>{
console.log("map:"+key+':'+value);
})
6、freeze(obj)
官方解释:可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。
理解:这个好理解,这个对象就“冻结了”,不能动
// 未冻结
let obj = {
name: 'obj',
age: 18,
eat : function(){}
};
// Object.freeze(obj)
obj.sex = 'nan'
delete obj.age
Object.defineProperty(obj, 'school', { value: "wudaokou" });
Object.assign(obj,{"ooo":"OOO"})
console.log(obj); //{name: 'obj', sex: 'nan', ooo: 'OOO', school: 'wudaokou', eat: ƒ}
// 冻结
let obj = {
name: 'obj',
age: 18,
eat : function(){}
};
Object.freeze(obj)
obj.sex = 'nan'
delete obj.age
Object.defineProperty(obj, 'school', { value: "wudaokou" });//TypeError: Cannot define property school, object is not extensible
Object.assign(obj,{"ooo":"OOO"})//TypeError: Cannot add property ooo, object is not extensible
console.log(obj); //{name: 'obj', age: 18, eat: ƒ}
7、fromEntries(可迭代的参数)
官方解释:把键值对列表转换为一个对象
理解:就是entries的反过来,支持的参数有数组(二维的),map对象(不知道是个啥,以后再瞅瞅)
const obj1 = Object.fromEntries([ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]);
const obj2= Object.fromEntries(new Map([ ['foo', 'bar'], ['baz', 42] ]))
console.log(obj1);
console.log(obj2);
8、getOwnPropertyDescriptor(obj,“属性名”)
官方解释:返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)
理解:获取对象里某个属性的描述符,描述符概念查看上文 3、defineProperties
const obj = {
name:'obj1',
age: 18
}
let descriptor = Object.getOwnPropertyDescriptor(obj,"name")
console.log(descriptor);
9、getOwnPropertyDescriptors(obj)
官方解释:用来获取一个对象的所有自身属性的描述符。
理解:上文的getOwnPropertyDescriptor是获取一个属性的描述符,这里是获取全部
const obj = {
name: 'obj1',
age: 18
}
let descriptor = Object.getOwnPropertyDescriptors(obj)
console.log(descriptor);
10、getOwnPropertyNames(obj)
官方解释:返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
理解:返回对象的属性,是个数组,包括不可枚举的
const obj = {
name:'obj1',
age: 18
}
let descriptor = Object.getOwnPropertyNames(obj)
console.log(descriptor); //['name', 'age']
10、getOwnPropertySymbols(obj)
官方解释:返回一个给定对象自身的所有 Symbol 属性的数组。
理解:返回对象里的所有Symbol属性,是个数组。
不了解啥属于Symbol,好像是新的一种数据类型,以后再看看。
11、getPrototypeOf(obj)
官网解释:返回指定对象的原型(内部[[Prototype]]属性的值)
理解:返回对象的"原型"。1、该方法返回的就是–参数对象的原型链(__proto__);2、通过create创建的对象的原型就是cerate的参数
// 1、方法返回的就是参数的原型链
const obj = {
name:'obj1',
age: 18
}
console.log(obj);
console.log(Object.getPrototypeOf(obj));
console.log(Object.getPrototypeOf(obj)===obj.__proto__); //true
// create创建的对象的原型就是cerate的参数
const obj = {
name: 'obj1',
age: 18
}
console.log(obj);
const object1 = Object.create(obj);
console.log(object1);
console.log(Object.getPrototypeOf(object1)===obj);
12、hasOwn(obj,“属性名”)
官方解释:如果指定的对象具有指定的属性作为其自己的属性,则静态方法返回 true。 如果属性被继承或不存在,则该方法返回 false。
理解:如果参数里的对象有这个属性,则返回true,反之false
const obj = {
name:'obj1',
age: 18
}
console.log(Object.hasOwn(obj,'name')); //true
console.log(Object.hasOwn(obj,'name1')); //false
13、is()
官方解释:判断两个值是否为同一个值
理解:同上
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
Object.is(null, null); // true
// 特例
Object.is(0, -0); // false
Object.is(0, +0); // true
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
14、isExtensible(obj)
官方解释:判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)
理解:判断对象可不可以增加新的属性
let obj = {
name:'obj1',
age: 18
}
console.log(Object.isExtensible(obj)); //true
let frozen = Object.freeze(obj); //被冻结了就不可扩展了
console.log(Object.isExtensible(frozen)); //false
15、isFrozen(obj)
官方解释:判断一个对象是否被冻结
解释:同上,冻结见上文6、freeze
let obj = {
name:'obj1',
age: 18
}
console.log(Object.isFrozen(obj)); //false
Object.freeze(obj); //冻结
console.log(Object.isFrozen(obj)); //true
PS:一个不可扩展的空对象同时也是个冻结对象
即:不可扩展的空对象是冻结对象。但是如果是有值的不可扩展的对象,那它不是冻结对象,因为它虽然不可扩展,但是可以修改原有的值。
另:把不可扩展的对象的属性全delete后,那它就成为了一个冻结东西
16、isSealed(obj)
官方解释:判断一个对象是否被密封
理解:同上,密封:不可扩展(不能新建key)且自身属性值(value)不可修改
let obj = {
name:'obj1',
age: 18
}
console.log(Object.isSealed(obj)); //false
console.log(Object.isSealed(Object.preventExtensions({}))); //true
console.log(Object.isSealed(Object.preventExtensions({name:'obj2'}))); //false
console.log(Object.isSealed(Object.freeze({}))); //true
console.log(Object.isSealed(Object.freeze({name: 'obj3'}))); //true
这里就多出了三个名词:扩展、冻结、密封
对应的定义三个状态的方法分别是:preventExtensions()、freeze()、seal()
对应的判断是否为改状态的三个方法是:isExtensible()、isFrozen()、isSealed()
17、keys(obj)
官方解释:返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致。
理解:返回对象的属性名,是个数组,顺序和正常遍历的一样
console.log(Object.keys(['a', 'b', 'c']));
console.log(Object.keys(['a', 2, ['a','b','c'],{name:'obj'}]));
console.log(Object.keys({ 0: 'a', 1: 'b', 2: 'c' }));
console.log(Object.keys({ 100: 'a', 2: 'b', 7: 'c' }));
console.log(Object.keys({name: 'obj1',age: 18}));
18、preventExtensions(obj)
官方解释:让一个对象变的不可扩展,也就是永远不能再添加新的属性。
理解:该对象不能新增属性,但是可以修改原有的,或者删除原有的
let obj = {
name:'obj1',
age: 18
}
Object.preventExtensions(obj)
obj.a = "a"
obj.name = 'obj2'
delete obj.age
console.log(obj);
19、seal(obj)
官方解释:封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。
理解:不能新增属性、不能删除属性,可以修改属性,但是不能修改属性为“访问性”属性(见上文3、defineProperties(obj, props)—get)
let obj = {
name: 'obj1',
age: 18
}
Object.seal(obj)
obj.a = 'a',
delete obj.name
obj.age = 20
console.log(obj);
Object.defineProperty(obj, 'age', {
get: function() { return 'g'; }
}); //Uncaught TypeError: Cannot redefine property: age at Function.defineProperty
20、setPrototypeOf(obj, prototype)
官方解释:设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null。
理解,把第一个对象的原型[[Prototopy]],变成第二个参数(一个对象或null)的原型
简而言之就是想修改对象的原型
至于有什么用,俺也不知道,也没有实际的应用场景,看看官网例子吧,知道有这么个东西就行。
21、values(obj)
官网解释:返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for…in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
理解:返回对象的值,是个数组
let obj = {
name:'obj1',
age: 18
}
console.log(Object.values(obj));
console.log(Object.values({ 100: 'a', 2: 'b', 7: 'c' }));
console.log(Object.values("obj"));