随着JavaScript的发展,JavaScript的Object构造函数也增加了许多方法(自身方法和原型链方法。有必要全面了解一下。本文基本涵盖了下Object所有的属性和方法介绍。如果有遗漏,还请指出。
一些未列出的属性或方法是非标准的、不推荐使用的或者已经从
Web标准中删除的,本文将不再进行介绍。
首先需要介绍一下JavaScript对象的属性描述符和对象属性的可枚举性的概念。
JS属性描述符(属性描述对象)
创建对象的方式有三种:第一种,通过new操作符后面跟Object构造函数,第二种,对象字面量方式。第三种,使用Object.create()方法。如下:
const obj = {x: 5,y: 6}
const obj1 = new Object()
obj1.x = 5
obj2.x = 6
const obj2 = Object.create(Object.prototype, {
x: {
value: 5
},
y: {
value: 6
}
})
上面这三种方式创建出来的对象是一样的,有相同的属性。但是这些属性内部都有描述其行为的属性描述符,保存该属性的一些元信息。如下图:
如果要获得对象的属性描述符,可以通过Object.getOwnPropertyDescriptor()来获取对象中某个属性的属性描述符。
const obj = { x: 5, y: 6 }
const desc = Object.getOwnPropertyDescriptor(obj, 'x')
/*
{
value: 5
writable: true
enumerable: true
configurable: true
}
*/
console.log(desc)
对象里目前存在的属性描述符有两种主要形式:数据属性描述符(data Property Descriptors )和访问器(accessor Property Descriptors)属性描述符。
属性描述符特性是为了实现 JavaScript 引擎用的,因此在 JavaScript 中不能直接访问它们。为了表示特性是内部值,该规范把它们放在了两对儿方括号中,例如[[Enumerable]]。
数据属性描述符
数据属性描述符有4个描述其行为的特性:
-
[[Configurable]]: 表示能否通过delete删除属性,能否修改属性的特性,或者能否把属性修改为访问器属性描述符。一旦为false,就不能再设置它的(value,writable,configurable)。直接在对象上定义的属性默认值为true。 -
[[Enumerable]]: 表示能否能通过for-in,Object.keys(),JSON.stringify(),Object.assign()遍历属性。默认值为true。 -
[[Writable]]: 表示能否修改属性的值。如果为false,属性的值就不能被重写,只能为只读。默认值为true。 -
[[Value]]: 包含这个属性的值。读取属性值的时候,从这个位置读。写入属性值时,把新值保存在这个位置。默认值是undefined。
访问器属性描述符
访问器属性有4个描述其行为的特性:
-
[[Configurable]]: 表示能否通过delete删除属性,能否修改属性的特性,或者能否把属性修改为数据属性描述符。一旦为false,就不能再设置它的(value,writable,configurable)。直接在对象上定义的属性默认值为true。 -
[[Enumerable]]: 表示能否能通过for-in,Object.keys(),JSON.stringify(),Object.assign()遍历属性。默认值为true。 -
[[Get]]: 在读取属性时调用的函数。默认值为undefined。 -
[[Set]]: 在写入属性时调用的函数。默认值为undefined。
数据属性描述符和访问器属性描述符的区别
任何属性描述符都可以有名为[[Configurable]]和[[Enumerable]]的字段。数据属性描述符含有 [[Writable]] 和 [[Value]] 特性,访问器属性描述符含有[[Get]]和[[Set]]特性。
如下图所示,绿色代表该属性下可存在的特性,红色代表不可存在的特性。
[[Writable]]、[[Value]]和[[Get]]、[[Set]]之间是互斥关系。因为一个属性,它不能既属于数据属性描述符,也属于访问器属性描述符。如果在Object.defineProperty中同时定义互斥特性会抛出异常。
JS属性的可枚举性
JavaScript对象的属性可分为可枚举和不可枚举。它是由内部“可枚举”标志(enumerable)决定的,true 为可枚举,false为不可枚举。
对于通过直接的赋值和属性初始化的属性,该标识值默认为即为true,对于通过Object.defineProperty ,Object.create 等定义的属性,该标识值默认为false。
const obj = { x: 5 }
Object.defineProperty(obj, 'y', {
value: 6
})
const desc1 = Object.getOwnPropertyDescriptor(obj, 'x')
// {value: 5, writable: true, enumerable: true, configurable: true}
console.log(desc1)
const desc2 = Object.getOwnPropertyDescriptor(obj, 'y')
// {value: 6, writable: false, enumerable: false, configurable: false}
console.log(desc2)
可枚举的属性可以通过for...in循环进行遍历(除非该属性名是一个 Symbol)。
一、 Object 构造函数属性
Object.prototype
JavaScript规定,每个函数都有一个prototype属性,指向一个对象。所以Object构造函数也会有一个prototype属性。几乎所有对象都继承了Object.prototype的属性。这就是所有对象都有valueOf和toString方法的原因,因为这是从Object.prototype继承的。
Object.length
函数的 length 得到的是形参个数。所以Object.length的形参个数是1。
function test1(a, b, c) { }
// 3
console.log(test1.length)
function test2(a, b, c, d) { }
// 4
console.log(test2.length)
// 1
console.log(Object.length)
Object.name
Object函数的name属性,返回该函数的函数名。
// Object
console.log(Object.name)
二、 Object 构造函数的方法
工具相关方法
Object.is()
Object.is()方法接收两个参数,判断两个值是否是相同的值。
传入一个参数或不传参的情况。
Object.is() // true
Object.is(123) // false
Object.is(undefined) // true
Object.is(null) // false
严格相等运算符(===)和Object.is()的区别。
+0 === -0 // true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
绝大多数情况下,Object.is()的结果与===运算符是相同的。除了+0,-0和NaN这两种情况使用===和Object.is()比较返回结果不同。
Object.assign()
Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
Array.from()可以传入多个参数:
- 第一个参数
target(必填):目标对象。 - 第N个参数
source:源对象。
Object.assign(target, ...sources)
如果不传参数或者传入null和undefined都会抛出异常。
// Uncaught TypeError: Cannot convert undefined or null to object
Object.assign()
Object.assign(null)
Object.assign(undefined)
基本用法。
const target = { id: 1 }
const source1 = { name: 'zhangsan' }
const source2 = { age: 26 }
const newObj = Object.assign(target, source1, source2)
// {id: 1, name: "zhangsan", age: 26}defineProperty
console.log(newObj)
如果只传入一个参数,Object.assign会直接返回该参数。
const target = { id: 1, name: '刘德华' }
const newObj = Object.assign(target)
// true
console.log(newObj === target)
如果非对象参数出现在源对象的位置,这些参数都会转成对象,如果无法转成对象,就会跳过。如果undefined和null不在首参数,就不会报错。
const target = { id: 1, name: '刘德华' }
const newObj = Object.assign(target, 123,true)
// {id: 1, name: "刘德华"}
console.log(newObj)
const target1 = { id: 1, name: '刘德华' }
// 源对象是字符串的话会以数组形式拷贝到目标对象
const newObj1 = Object.assign(target1, '张学友')
// {0: "张", 1: "学", 2: "友", id: 1, name: "刘德华"}
console.log(newObj1)
// 其他值都不会产生效果
let target2 = { id: 1 };
Object.assign(target2, undefined) === target2 // true
Object.assign(target2, null) === target2 // true
Object.assign(target2, NaN) === target2 // true
Object.assign(target2, false) === target2 // true
Object.assign(target2, 10) === target2 // true
如果目标对象与源对象有同名属性,或多个源对象有同名属性,后面的属性就会覆盖前面的属性。
const target = { id: 1, name: '刘德华' }
const source1 = { name: '张学友', age: 50 }
const source2 = { age: 26 }
const newObj = Object.assign(target, source1, source2)
// {id: 1, name: "张学友", age: 26}
console.log(newObj)
Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable:false)。Object.assign方法是浅拷贝,而不是深拷贝。如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
获取和设置对象原型的相关方法
Object.create()
Object.create() 方法会使用指定的原型对象及属性去创建一个新的对象。
Object.create()可以传入2个参数:
- 第一个参数
proto(必填):新创建对象的原型对象,不传会抛出异常。 - 第二个参数
propertiesObject(可选):要添加到新创建对象的属性描述符(新添加的属性是其自身的属性,而不是其原型链上的属性)。
如果不传参数,传入undefined或传入基本数据类型会抛出异常。
// Object prototype may only be an Object or null
Object.create(undefined)
Object.create(123)
Object.create('abc')
传入null的情况。
const obj = Object.create(null)
console.log(obj)
传入null的的时候,也就是将null设置成了新创建对象的原型,这个新对象就不会有原型链了。所以新对象是非常干净的对象。
使用对象自变量和直接使用 new Object() 创建对象。
const obj = {}
console.log(obj)
const obj1 = new Object()
console.log(obj1)
从上图可以看出,使用对象自变量和直接使用new Object()创建对象的时候,都会继承Object构造函数的原型对象。这也是它们和使用Object.create(null)创建出新对象的区别。
传入对象的情况。
// 自定义原型对象
const customPropertyObject = { id: 1, name: 'zhangsan' }
const obj = Object.create(customPropertyObject)
console.log(obj);
从上图可以看出 customPropertyObject被定义在了新创建对象的原型对象上,customPropertyObject又继承了Object构造函数的原型对象。
也可以直接使用来指定Object.create(Object.prototype)创建出和对象自变量一样的对象。
const obj = Object.create(Object.prototype)
console.log(obj)
这和通过 const obj = {} 直接创建对象是一样的效果。
传入2个参数。
const obj = Object.create({ id: 1 }, {
name: {
value: 'zhangsan',
enumerable: true,
configurable: true,
writable: true,
},
age: {
value: 20,
enumerable: false,
configurable: false,
writable: false,
}
})
console.log(obj)
从上图可以看到,第二个参数添加的属性是创建出的对象自身的属性。我们把age属性设置成了不可删除,不可枚举,不可修改的属性值。
obj.age = 1
delete obj.age
// id
// name
for (let prop in obj) {
console.log(prop);
}
从上图可以看出,当修改,删除obj.age属性的时候是没有效果的,而且也没有办法通过for in循环出来。
第二个参数传入null会抛出异常。
// Uncaught TypeError:Cannot convert undefined or null to object
const obj = Object.create(null, null)
Object.getPrototypeOf()
Object.getPrototypeOf()方法返回指定对象的原型,如果没有继承属性,则返回 null。
const obj = { id: 1, name: 'zhangsan' }
// 获取的是Object的原型对象,这里省略打印...
const propertyObj = Object.getPrototypeOf(obj)
// true
console.log(propertyObj === Object.prototype)
function Car() { }
const newCar = new Car()
// true
console.log(Object.getPrototypeOf(newCar) === Car.prototype)
// Object的原型对象上没有原型对象了,就返回了null
// null
console.log(Object.getPrototypeOf(Object.prototype));
// null
console.log(Object.getPrototypeOf({}.__proto__));
使用Object.create创建对象,并使用Object.getPrototypeOf()获取它的原型对象。
const obj = Object.create({ id: 1 })
const propertyObj = Object.getPrototypeOf(obj)
// {id: 1}
console.log(propertyObj)
Object.setPrototypeOf()
Object.setPrototypeOf()方法为指定对象设置原型,返回该指定对象。
Object.setPrototypeOf()可以传入2个参数:
- 第一个参数
obj(必填):要设置其原型的对象。 - 第二个参数
prototype(可选):该对象的新原型(一个对象 或null)。
const son = { id: 1, name: 'zhangsan' }
// 要设置的原型对象
const father = { money: 100 }
const obj = Object.setPrototypeOf(son, father)
console.log(obj)
上图可以看出,Object.setPrototypeOf方法将对象son的原型,设置为对象father,因此son可以共享father的属性。
const obj = Object.setPrototypeOf({}, null)
// 会返回一个非常干净的空 {} 对象,没有继承任何原型对象。
console.log(obj)
如果传入错误参数类型,会抛出异常。
// Uncaught TypeError: Object prototype may only be an Object or null: undefined
const obj = Object.setPrototypeOf(1)
const obj = Object.setPrototypeOf(null)
const obj = Object.setPrototypeOf(undefined)
// 第二个参数:Uncaught TypeError: Object prototype may only be an Object or null
const obj = Object.setPrototypeOf({}, undefined)
Object操作属性描述符的相关方法
Object.defineProperty()
Object.defineProperty方法允许通过属性描述符(数据属性描述符和访问器属性描述符),设置或修改一个属性,然后返回修改后的原对象。
Object.defineProperty()可以传入3个参数:
- 第一个参数
obj(必填):属性所在的对象。 - 第二个参数
prop(可选):属性名。 - 第三个参数
descriptor(必填):属性描述符。
Object.defineProperty设置属性的时候,如果属性不存在,则创建属性。如果属性已经存在,Object.defineProperty方法相当于更新该属性的属性描述对象。
如果参数错误或不填,会抛出异常。
// Uncaught TypeError: Object.defineProperty called on non-object
Object.defineProperty()
Object.defineProperty(1)
// Uncaught TypeError: Property description must be an object: undefined
Object.defineProperty({})
// Uncaught TypeError: Property description must be an object: 1
Object.defineProperty({}, 'abc', 1)
使用Object.defineProperty()定义数据属性描述符
const obj = { id: 1 }
const newObj = Object.defineProperty(obj, 'name', {
value: 'zhangsan',
writable: false,
enumerable: true,
configurable: true
})
// true
console.log(obj === newObj)
//{id: 1, name: "zhangsan"}
console.log(obj)
newObj.id = 10
// 不可修改,严格模式下会抛出异常
newObj.name = 'lisi'
//{id: 10, name: "zhangsan"}
console.log(obj)
使用Object.defineProperty()定义访问器属性描述符
const obj = { id: 1 }
Object.defineProperty(obj, 'name', {
enumerable: true,
configurable: true,
set(newValue) {
console.log('监听对象属性修改--->我的值是:' + newValue)
},
get() {
console.log('获取对象属性');
return '刘德华' //先硬编码
}
})
// 监听对象属性修改--->我的值是:zhangsan
obj.name = 'zhangsan'
// 获取对象属性
//刘德华
console.log(obj.name)
上面这个obj.name赋值或者取值的时候会分别触发 set 和 get 对应的函数。set 和 get相当于监听函数。
模拟一个访问和设置的默认行为,达到我们正确的修改数据和访问数据是正确的。
const obj = { id: 1 }
// 内部 this 指向 obj
Object.defineProperty(obj, 'name', {
enumerable: true,
configurable: true,
set(newValue) {
this.name = newValue
},
get() {
return this.name
}
})
// Uncaught RangeError: Maximum call stack size exceeded
obj.name = 'zhangsan'
按照上面这么写的话会造成循环引用。obj.name = 'zhangsan' 会触发set函数,set函数内部 this.name = newValue又会触发set函数。然后无限调用....就抛出异常。需要定义一个新的属性解决问题。
const obj = { id: 1 }
// 内部 this 指向 obj
Object.defineProperty(obj, 'name', {
enumerable: true,
configurable: true,
set(newValue) {
this._name = newValue
},
get() {
return this._name || undefined
}
})
obj.name = 'zhangsan'
上面这样做法有一个缺点,就是obj对象里多了一个_name属性。
Object.defineProperties()
Object.defineProperties方法允许通过属性描述符(数据属性描述符和访问器属性描述符),定义或修改多个属性,然后返回修改后的原对象。
Object.defineProperties()可以传入2个参数:
- 第一个参数
obj(必填):属性所在的对象。 - 第二个参数
prop(可选):属性描述符对象。
如果参数错误或不填,会抛出异常。
// Uncaught TypeError: Object.defineProperty called on non-object
Object.defineProperties()
Object.defineProperties(1,{})
// Cannot convert undefined or null to object
Object.defineProperties({})
Object.defineProperties({},null)
const obj = { id: 1 }
Object.defineProperties(obj, {
name: { value: 'zhangsan', enumerable: true, writable: true },
age: { value: 20, enumerable: true, writable: true },
})
// {id: 1, name: "zhangsan", age: 20}
console.log(obj)
注意:
Object.defineProperty()和Object.defineProperties()的属性描述符对象,它的writable、configurable、enumerable这三个属性的默认值都为false。
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()可以取得指定对象上一个自有属性(非继承属性)的描述符。如果指定的属性存在于对象上,则返回其属性描述符对象(property descriptor),否则返回 undefined。
Object.getOwnPropertyDescriptor()可以传入2个参数:
- 第一个参数
obj(必填):属性所在的对象。 - 第二个参数
prop(可选):属性名称。
如果不传参数,会抛出异常。
// Uncaught TypeError: Cannot convert undefined or null to object
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor(null)
Object.getOwnPropertyDescriptor(undefined)
const obj = { id: 1, name: 'zhangsan' }
Object.defineProperty(obj, 'name', {
enumerable: true,
configurable: true,
get() {
return 'get'
},
set() {
return 'set'
}
})
const descObj = Object.getOwnPropertyDescriptor(obj, 'id')
// {value: 1, writable: true, enumerable: true, configurable: true}
console.log(descObj)
// get和set是两个函数
// {enumerable: true, configurable: true, get: ƒ, set: ƒ}
const descObj1 = Object.getOwnPropertyDescriptor(obj, 'name')
console.log(descObj1);
// 因为toString是原型链上的对象,所以访问不到
// undefined
const descObj2 = Object.getOwnPropertyDescriptor(obj, 'toString')
console.log(descObj2);
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors()方法,返回指定对象所有自身属性(非继承属性)的属性描述符对象。如果没有任何自身属性,返回空对象。
Object.getOwnPropertyDescriptors()可以传入1个参数:
- 第一个参数
obj(必填):任意对象
如果不传参数或传入错误参数,会抛出异常。
// Uncaught TypeError: Cannot convert undefined or null to object
Object.getOwnPropertyDescriptors()
Object.getOwnPropertyDescriptors(null)
Object.getOwnPropertyDescriptors(undefined)
const obj = {
id: 1,
name: 'zhangsan'
};
const descObj = Object.getOwnPropertyDescriptors(obj)
/* {
id:{
value: 1,
writable: true,
enumerable: true,
configurable: true
},
name: {
value: 1,
writable: true,
enumerable: true,
configurable: true
}
}
*/
console.log(descObj)
Object.getOwnPropertyDescriptors()方法返回一个对象,所有原对象的属性名都是该对象的属性名,对应的属性值就是该属性的属性描述符对象。
Object转换的相关方法
Object.keys()
Object.keys() 方法会返回由一个指定对象自身(非继承属性)可枚举属性组成的字符串数组。
const obj = {
id: 1,
name: 'zhangsan'
};
const props = Object.keys(obj)
// ["id", "name"]
console.log(props)
Object.keys()可以传入1个参数:
- 第一个参数
obj(必填):任意对象
如果不传参数,会抛出异常。
// Uncaught TypeError: Cannot convert undefined or null to object
Object.keys()
Object.keys(null)
Object.keys(undefined)
const obj = {
id: 1,
name: 'zhangsan'
};
const props = Object.keys(obj)
// ["id", "name"]
console.log(props)
const obj1 = { 100: 'a', 2: 'b', 7: 'c' };
// ['2', '7', '100']
console.log(Object.keys(obj1));
Object.values()
Object.values()方法返回由一个指定对象自身(非继承属性)可枚举属性值的数组。
Object.values()可以传入1个参数:
- 第一个参数
obj(必填):任意对象
如果不传参数,会抛出异常。
// Uncaught TypeError: Cannot convert undefined or null to object
Object.values()
Object.values(null)
Object.values(undefined)
const obj = {
id: 1,
name: 'zhangsan'
}
const newObj = Object.values(obj)
// [1, "zhangsan"]
console.log(newObj)
Object.entries()
Object.entries()方法返回由一个指定对象自身(非继承属性)可枚举属性的键值对数组。
Object.entries()可以传入1个参数:
- 第一个参数
obj(必填):任意对象
如果不传参数,会抛出异常。
// Uncaught TypeError: Cannot convert undefined or null to object
Object.entries()
Object.entries(null)
Object.entries(undefined)
const obj = {
id: 1,
name: 'zhangsan'
}
const newObj = Object.entries(obj)
// [['id',1],['name','zhangsan']]
console.log(newObj)
for (let [key, value] of Object.entries(obj)) {
// id: 1
// name: zhangsan
console.log(`${key}: ${value}`);
}
Object.fromEntries()
Object.fromEntries()方法是Object.entries()的逆操作,用于将一个键值对数组转为对象。
Object.fromEntries()可以传入1个参数:
- 第一个参数
iterable(必填):可迭代对象,类似Array、Map或者其它可迭代的对象。
如果不传参数或传入参数错误,会抛出异常。
// Uncaught TypeError: undefined is not iterable
Object.fromEntries()
Object.fromEntries(undefined)
Object.fromEntries(null)
// Uncaught TypeError: function is not iterable
Object.fromEntries(() => {})
// Uncaught TypeError: Iterator value a is not an entry object
Object.fromEntries('abc')
const map = new Map([['id', 1], ['name', 'zhangsan']])
const obj = Object.fromEntries(map)
// {id: 1, name: "zhangsan"}
console.log(obj)
const obj1 = Object.fromEntries([['id', 1], ['name', 'zhangsan']])
// {id: 1, name: "zhangsan"}
console.log(obj1)
Object.getOwnPropertyNames()
Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性(非继承属性)的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的字符串数组。
Object.getOwnPropertyNames()可以传入1个参数:
- 第一个参数
obj(必填):任意对象。
如果不传参数或传入参数错误,会抛出异常。
// Uncaught TypeError: Cannot convert undefined or null to object
Object.getOwnPropertyNames()
Object.getOwnPropertyNames(undefined)
Object.getOwnPropertyNames(null)
const obj = { id: 1, name: 'zhangsan' }
const arr = Object.getOwnPropertyNames(obj)
// ["id", "name"]
console.log(arr)
Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols()方法返回一个指定对象自身的所有Symbol属性的数组。所有的对象在初始化的时候不会包含任何的Symbol,除非你在对象上赋值了Symbol否则Object.getOwnPropertySymbols()只会返回一个空的数组。
Object.getOwnPropertySymbols()可以传入1个参数:
- 第一个参数
obj(必填):任意对象。
如果不传参数或传入参数错误,会抛出异常。
// Uncaught TypeError: Cannot convert undefined or null to object
Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols(undefined)
Object.getOwnPropertySymbols(null)
const obj = { id: 1, name: 'zhangsan' }
obj[Symbol('age')] = 20
const arr = Object.getOwnPropertySymbols(obj)
// [Symbol(age)]
console.log(arr);
Object对象的防篡改相关方法
Object.preventExtensions()
Object.preventExtensions()方法让一个对象变的不可扩展,永远不能再添加新的属性。返回已经不可扩展的原对象。
Object.preventExtensions()可以传入1个参数:
- 第一个参数 obj :任意对象。
const obj = { id: 1, name: 'zhangsan' }
const newObj = Object.preventExtensions(obj)
// 在严格模式下,会抛出异常。
obj.age = 20
// {id: 1, name: "zhangsan"}
console.log(obj)
// true
console.log(obj === newObj)
Object.isExtensible()
Object.isExtensible()方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。返回true是可扩展的。
Object.isExtensible()可以传入1个参数:
- 第一个参数
obj:任意对象。
const obj = { id: 1, name: 'zhangsan' }
// true
console.log(Object.isExtensible(obj))
Object.preventExtensions(obj)
// false
console.log(Object.isExtensible(obj))
Object.seal()
Object.seal()方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置([[Configurable]]设置为false)。当前属性的值只要封闭之前是可写的就还是可写的。返回被密封的的原对象。
Object.seal()可以传入1个参数:
- 第一个参数
obj:任意对象。
const obj = { id: 1, name: 'zhangsan' }
Object.seal(obj)
// 不能新增, 严格模式下抛出异常
obj.age = 20
// 不能删除,严格模式下抛出异常
delete obj.id
Object.isSealed()
Object.isSealed() 方法判断一个对象是否被密封。返回true是被密封的。
Object.isSealed()可以传入1个参数:
- 第一个参数
obj:任意对象。
Object.freeze()
Object.freeze() 方法冻结一个对象。一个被冻结的对象再也不能被修改。冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改已有属性的值。也不能修改该对象已有属性的可枚举性、可配置性、可写性,以及。并且冻结一个对象后该对象的原型也不能被修改。freeze()返回原对象。
Object.freeze()可以传入1个参数:
- 第一个参数
obj:任意对象。
const obj = { id: 1, name: 'zhangsan',house: { 'beijing': 2 } }
Object.freeze(obj)
// 不能新增属性, 严格模式下抛出异常
obj.age = 20
// 不能删除属性,严格模式下抛出异常
delete obj.id
// 不能修改属性,严格模式下抛出异常
obj.id = 20
// 不能修改原型链,严格模式下抛出异常
obj.__proto__ = {}
// 不能修改属性描述符,严格模式下抛出异常
Object.defineProperty(obj, 'id', {
enumerable: false
})
// 如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象。
obj.house.beijing = 3
// 3
console.log(obj.house.beijing)
被冻结对象自身的所有属性几乎都不可能以任何方式被修改。
Object.isFrozen()
Object.isFrozen()方法判断一个对象是否被冻结。返回true是被冻结的。
Object.isFrozen()可以传入1个参数:
- 第一个参数
obj:任意对象。
const obj = { id: 1, name: 'zhangsan' }
Object.freeze(obj)
// true
console.log(Object.isFrozen(obj))
三、 Object 实例对象(Object 原型)的属性和方法
Object.prototype.constructor
prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数。因为Object是一个函数,所以它的原型对象上的constructor属性就是Function。
// true
console.log(Object.__proto__.constructor === Function)
Object.prototype.hasOwnProperty()
对象实例的hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。
Object.prototype.hasOwnProperty()可以传入1个参数:
- 第一个参数
obj:要检测的属性的字符串名称,或者Symbol。
const obj = { id: 1, name: 'zhangsan' }
// true
console.log(obj.hasOwnProperty('id'))
// false
console.log(obj.hasOwnProperty('toString'))
Object.prototype.isPrototypeOf()
对象实例的isPrototypeOf()方法用来判断该对象是否为参数对象的原型。
Object.prototype.isPrototypeOf()可以传入1个参数:
- 第一个参数
obj:在该对象的原型链上搜索
var father = { money: 100 };
var son = Object.create(father);
// true 儿子的原型是爸爸
console.log(father.isPrototypeOf(son))
//由于Object.prototype处于原型链的最顶端,所以对各种实例都返回true,只有直接继承自null的对象除外
Object.prototype.isPrototypeOf({}) // true
Object.prototype.isPrototypeOf([]) // true
Object.prototype.isPrototypeOf(/xyz/) // true
Object.prototype.isPrototypeOf(Object.create(null)) // false
Object.prototype.propertyIsEnumerable()
对象实例的propertyIsEnumerable()方法返回一个布尔值,表示指定的属性是否可枚举。
Object.prototype.对象实例的propertyIsEnumerable()可以传入1个参数:
- 第一个参数
prop:属性名
const obj = { id: 1, name: 'zhangsan' }
Object.defineProperty(obj, 'age', {
enumerable: false
})
// true
console.log(obj.propertyIsEnumerable('id'))
// false
console.log(obj.propertyIsEnumerable('age'))
// false
console.log(obj.propertyIsEnumerable('toString'))
Object.prototype.toLocaleString()
对象实例的toLocaleString() 方法返回一个该对象的字符串表示。Object toLocaleString 返回的是调用 toString() 的结果。
const obj = { id: 1, name: 'zhangsan' }
// [object Object]
console.log(obj.toLocaleString())
Object.prototype.toString()
对象实例的toString() 方法返回一个表示该对象的字符串。
toString() 检测对象类型。
var toString = Object.prototype.toString;
console.log(toString.call(new Date())) // [object Date]
console.log(toString.call({})) // [object Object]
console.log(toString.call('')) // [object String]
Object.prototype.valueOf()
对象实例的 valueOf() 方法返回指定对象的原始值。
const emptyObject = {}
// true
console.log(emptyObject.valueOf() === emptyObject)
const arr = []
// true
console.log(arr.valueOf() === arr)
参考
developer.mozilla.org/zh-CN/docs/…
es6.ruanyifeng.com/#docs/objec…