Object.create(proto, [propertiesObject])
方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
proto新创建对象的原型对象。propertiesObject可选。需要传入一个对象,该对象的属性类型参照Object.defineProperties()的第二个参数。如果该参数被指定且不为 undefined,该传入对象的自有可枚举属性(即其自身定义的属性,而不是其原型链上的枚举属性)将为新创建的对象添加指定的属性值和对应的属性描述符。
let proto = {
name: 'wang',
age: 22
}
let obj = Object.create(proto,{
sex:{
value: 'boy',
writable: true
}
})
console.log(obj.name) // wang
console.log(obj) // { sex: 'boy }
Object.defineProperty(obj, prop, descriptor)
方法直接在一个对象上定义一个新的属性或者修改现有属性,并返回该对象
obj在其上定义或修改属性的对象。prop要定义或修改的属性的名称或Symbol。descriptor要定义或修改的属性描述符。
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。
这两种描述符都是对象。它们共享以下可选键值(默认值是指在使用 Object.defineProperty() 定义属性时,省略字段的默认值):
-
configurable
当且仅当该属性的configurable键值为true时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false。 -
enumerable
当且仅当该属性的enumerable键值为true时,该属性才会出现在对象的枚举属性中,在枚举对象属性时会被枚举到(for...in或Object.keys方法)。默认为false。 -
value
该属性对应的值。可以是任何有效的JavaScript值(数值,对象,函数等)。默认为undefined。 -
wriatable
当且仅当该属性的writable键值为true时,属性的值,也就是上面的value,才能被赋值运算符改变。默认为false。 -
set
属性的setter函数,如果没有setter,则为undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。默认为undefined。 -
get
属性的getter函数,如果没有getter,则为undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。默认为undefined。
| configurable | enumerable | value | writable | get | set | |
|---|---|---|---|---|---|---|
| 数据描述符 | 可以 | 可以 | 可以 | 可以 | 不可以 | 不可以 |
| 存取描述符 | 可以 | 可以 | 不可以 | 不可以 | 可以 | 可以 |
let obj = {}
Object.defineProperty(obj, 'sex', {
value: 'boy',
writable: true,
enumerable: false,
configurable: true, // configurable:true 时可以重新定义属性描述符
})
Object.defineProperty(obj, 'age', {
value: 22,
writable: false,
enumerable: true,
configurable: false // configurable:false 时不能重新定义属性描述符
})
console.log(Object.entries(obj)) // [["age", 22]]
// Object.defineProperty(obj, 'age', {
// value: 44,
// writable: true,
// enumerable: false,
// configurable: true
// })
// 报错 Uncaught TypeError: Cannot redefine property: age 因为第一次定义 'age' 时 configurable:false 所以不能重新定义
Object.defineProperty(obj, 'sex', {
value: 'boy',
writable: false,
enumerable: true,
configurable: true,
})
console.log(Object.entries(obj)) // [ ["sex", "boy"], ["age", 22]]
Object.defineProperties(obj, props)
方法直接在一个对象上定义一个或多个新的属性或修改现有属性,并返回该对象。
obj在其上定义或修改属性的对象。props要定义其可枚举属性或修改的属性描述符的对象。对象中存在的属性描述符主要有两种:数据描述符和访问器描述符(更多详情,请参阅Object.defineProperty())。
let obj = { sex: 'girl' }
Object.defineProperties(obj, {
sex: {
writable: false // false 时赋值语句改变不了sex的值
},
age: {
value: 100,
writable: true
}
})
obj.sex = 'boy'; // 不能改变值
obj.age = 22; // 可以改变值
console.log(obj) // { sex: 'girl', age: 22 }
Object.defineProperties(obj, {
sex: {
value: 'boy' // 可以改变值
},
})
console.log(obj) // { sex: 'boy' }
function Archiver() {
let temperature = null;
let archive = [];
Object.defineProperty(this, 'temperature', {
get: function() {
console.log('get!');
return temperature;
},
set: function(value) {
temperature = value;
archive.push({ val: temperature });
}
});
this.getArchive = function() { return archive; };
}
let arc = new Archiver();
arc.temperature; // 'get!'
arc.temperature = 11;
arc.temperature = 13;
arc.getArchive(); // [{ val: 11 }, { val: 13 }]
Object.getOwnPropertyDescriptor
方法会返回某个对象属性的描述对象
Object.getOwnPropertyDescriptors
方法返回指定对象所有自身属性(非继承属性)的描述对象。
const obj = {
foo: 123,
get bar() { return 'abc' }
};
Object.getOwnPropertyDescriptors(obj)
// { foo:
// { value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:
// { get: [Function: get bar],
// set: undefined,
// enumerable: true,
// configurable: true } }
该方法的引入目的,主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。
const people = {
set name(value) {
console.log(value);
}
};
const target = {};
Object.assign(target, people);
Object.getOwnPropertyDescriptor(target, 'name')
// { value: undefined, 这是因为Object.assign方法总是拷贝一个属性的值,而不会拷贝它背后的赋值方法或取值方法。
// writable: true,
// enumerable: true,
// configurable: true }
Object.getOwnPropertyDescriptors()方法配合Object.defineProperties()方法,就可以实现正确拷贝。
const source = {
set name(value) {
console.log(value);
}
};
const target = {};
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
Object.getOwnPropertyDescriptor(target, 'name')
// { get: undefined,
// set: [Function: set name],
// enumerable: true,
// configurable: true }
Object.is()
用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
不同之处只有两个:一是+0 不等于 -0 ,二是 NaN 等于自身。
Object.assign()
方法用于对象的合并,将源对象(
source)的所有可枚举属性,复制到目标对象(target)。
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3, b: 'source2' };
Object.assign(target, source1, source2);
target // { a: 1, b: 'source2', c: 3 }
Object.setPrototypeOf()
方法的作用与
__proto__相同,用来设置一个对象的原型对象(prototype),返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
Object.getPrototypeOf()
该方法与
Object.setPrototypeOf()方法配套,用于读取一个对象的原型对象。
Object.values()
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(
enumerable)属性的键值。
Object.keys()
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(
enumerable)属性的键名。
Object,entries()
方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(
enumerable)属性的键值对数组。
Object.fromEntries()
方法是``Object.entries()` 的逆操作,用于将一个键值对数组转为对象。
该方法的一个用处是配合URLSearchParams对象,将查询字符串转为对象。
Object.fromEntries(new URLSearchParams('foo=bar&baz=qux'))
// { foo: "bar", baz: "qux" }
Object.getOwnPropertyNames(obj)
方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括
Symbol值作为名称的属性)组成的数组。
Object.getOwnPropertySymbols(obj)
返回对象自有的Symbol属性,原型链上的属性不会被获取。返回值是存储自有
Symbol属性的数组。
let name = Symbol.for('name');
let obj = {
[name]: 'name',
}
Object.defineProperties(obj, {
age: {
value: 22,
enumerable: false,
writable: true
},
sex: {
value: 'boy',
enumerable: false,
writable: true
}
})
console.log(Object.getOwnPropertyNames(obj)); // ["age", "sex"]
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(name)]
Object.preventExtensions(obj)
方法用于将一个对象设置为不可扩展,也就是不能再为其添加新的属性。
Object.isFrozen(obj)
方法用于判断一个对象是否已冻结。
Object.freeze(obj)
方法用于冻结一个对象。即将对象设置为不可扩展、将对象的所有自有的属性和方法(包括Symbol值的属性和方法)配置为不可配置、不可写。
Object.isSealed()
方法用于判断一个对象是否是已密封的状态。密封状态是指一个对象是不可扩展的,且所有自有属性和方法都是不可配置的。
Object.seal(obj)
方法用于密封一个对象,即将对象设置为不可扩展,同时将对象的所有自有属性都设置为不可配置(包括Symbol值的属性)。也就是说,不能给对象添加新的属性和方法,也不能删除现有的属性和方法、不能修改现有属性和方法的配置。但如果对象的属性和方法是可写的,那该属性和方法仍然可以修改。
Object.isExtensible(obj)
方法用于判断一个对象是否是可扩展的。
默认情况下,对象都是可以扩展的,即对象可以添加新的属性和方法。使用Object.preventExtensions()、Object.seal()和Object.freeze()方法都可以标记对象为不可扩展。
在ES5中,如果参数是非对象类型,会抛出TypeError异常。
在ES6中,如果参数是非对象类型,则会认为是一个不可扩展的普通对象,因此会返回false。
Object.preventExtensions()
方法用于将一个对象设置为不可扩展,也就是不能再为其添加新的属性。
对象默认是可扩展的,即可以添加新的属性。如果一个对象被配置为不可扩展,则无法添加新的属性,这是一个不可逆的操作。不可扩展的对象仍然可以删除已有的属性(取决于属性的可配置性),但如果尝试添加新的属性到不可扩展对象,会引发TypeError异常(严格模式)或静默失败。
Object.preventExtensions()仅阻止添加自身的属性。但属性仍然可以添加到对象原型,而这个不可扩展的对象同样会继承这些后来添加的原型对象的属性。