Object 详解
Object 详解
1. Object 介绍
1.1 作用
通俗来讲Object就是用来存储数据的一种容器,利用对象可以统一管理多个数据。
1.2 Object 的组成
- 属性:属性名(字符串)和属性值(任意类型)
- 方法:一种特殊的属性(属性值是函数)
1.3 如何访问对象
- .属性名:编码简单,特殊情况下不能使用
- 属性名包含特殊字符(- 空格)时不可使用
- 变量名不确定时
- [‘属性名’]:编码复杂,但是通用
1.4 判断
可以利用 instanceof 来判断对象的具体类型
var obj = {};
console.log(obj instanceof Object); // true
var arr= [];
console.log(arr instanceof Array); // true
code 1-1:instanceof 应用案列
2. Object 创建
2.1 Object构造函数模式
- 适用场景:不确定对象内部数据
- 缺点:语句太多
var p = new Object()
p.name = '十一'
p.age = 24
p.getName = function(){
console.log(this.name)
}
code 2-1:Object 创建之Object 构造函数模式
2.2 对象字面量模式
- 适用场景:确定对象内部数据
- 缺点:若是创建多个,会有重复代码
var p = {
name: '十一',
age: 24,
getName: function(){
console.log(this.name)
}
}
var p2 = {
name: 'Tom',
age: 12,
getName: function(){
console.log(this.name)
}
}
code 2-2:Object 创建之对象字面量模式
2.3 工厂函数模式
- 工厂函数:返回一个对象的函数就是工厂函数
- 适用场景:需要创建多个对象时
- 缺点:所创建的对象没有具体的类型,都是Object类型
function createPerson(name, age){
var obj = {
name: name,
age: age,
getName: function(){
console.log(this.name)
}
}
return obj
}
var p1 = createPerson('十一',24)
p1.getName();
var p2 = createPerson('Tom',24)
p2.getName();
code 2-3:Object 创建之工厂函数模式
2.4 自定义构造函数模式
- 适用场景:需要创建多个具有确定类型的对象
- 缺点:每个对象都有相同的方法数据,浪费内存
function Person(name, age){
this.name = name
this.age = age
this.getName = function(){
console.log(this.name)
}
}
var p1 = new Person('十一',24)
p1.getName();
code 2-4:Object 创建之自定义构造函数模式
2.5 构造函数据+原型的组合模式
- 使用方式:就是将公共的方法添加到构造函数的原型链__proto__上
- 适用场景:需要创建多个具有确定类型的对象
function Person(name, age){
this.name = name
this.age = age
}
Person.prototype.getName = function(){
console.log(this.name)
}
var p1 = new Person('十一',24)
p1.getName();
code 2-5:Object 创建之构造函数据+原型的组合模式
3. Object 属性
3.1 Object.defineProperty()
3.1.1 作用
在一个对象上定义新的属性或者修改现有的属性,并返回该对象
3.1.2 数据描述符(数据属性)
- value:该属性对应的值
- writable:属性值是否可修改。默认不可修改,true表示可修改
- configurable:属性是否可修改。默认不可修改,true表示可修改
- enumerable:属性是否可枚举(for…in 循环)。默认不可以,true表示可以
var obj = { name: '十一' } // 给 obj 添加一个新的属性为age,值为24,且可以修改属性和属性值,也可以进行遍历操作 Object.defineProperty(obj, 'age', { value: 24, write: true, configurable: true, enumerable: true }) console.log(obj) // {name: "十一", age: 24}
code 3-1:Object.defineProperty() 之数据描述符
3.1.2 存取描述符(访问器属性)
- get:给属性提供getter的方法
- set:给属性提供setter的方法
- configurable:属性是否可修改
- enumerable:属性是否可枚举(循环)
var obj = { name: '十一' } // 动态修改h1标签内容 var h1Html = document.getElementById("H1"); Object.defineProperty(obj, 'h1Html', { get: function(){ return h1Html.innerHTML; }, set: function(val){ h1Html.innerHTML = val; }, configurable: true, enumerable: true }) console.log(obj) // {name: "十一", h1Html: 获取到的h1标签的内容}
code 3-2:Object.defineProperty() 之存取描述符
3.1.3 相关方法
- Object.seal():禁止对象配置,描述符中的configurable设置为false
- Object.isSealed():判断对象是否被禁止对象配置操作 false:可以配置 true:禁止配置
var obj = {} var obj1 = {} Object.seal(obj) // 添加 Object.seal(obj) 再执行以下注释代码会报错:大概意思就是obj对象不支持扩展 // Object.defineProperty(obj, 'age', { // value: 24, // write: true, // configurable: true, // enumerable: true // }) Object.defineProperty(obj1, 'age', { value: 24, write: true, configurable: true, enumerable: true }) console.log(obj1) // { age: 24 } console.log(Object.isSealed(obj)) // true console.log(Object.isSealed(obj1)) // false
code 3-3:Object.defineProperty() 之对象配置
- Object.freeze():冻结对象,描述符中的writable设置为false,configurable设置为false
- Object.isFrozen():判断对象是否被冻结 false:未冻结 true:冻结
var obj = {} var obj1 = {} Object.freeze(obj) // 添加 Object.freeze(obj) 再执行以下注释代码会报错:大概意思就是obj对象不支持扩展 // Object.defineProperty(obj, 'age', { // value: 24, // write: true, // configurable: true, // enumerable: true // }) Object.defineProperty(obj1, 'age', { value: 24, write: true, configurable: true, enumerable: true }) console.log(obj1) // { age: 24 } console.log(Object.isFrozen(obj)) // true console.log(Object.isFrozen(obj1)) // false
code 3-4:Object.defineProperty() 之对象冻结
- Object.preventExtensions():禁止对象扩展,不能添加新属性但是可以删除已有属性
- Object.isExtensible():判断对象是否可以扩展 false:禁止扩展 true:可以扩展
var obj = { name: '十一' } var obj1 = { name: '十一' } Object.preventExtensions(obj) // 添加 Object.freeze(obj) 再执行以下注释代码会报错:大概意思就是obj对象不支持扩展 // Object.defineProperty(obj, 'age', { // value: 24, // write: true, // configurable: true, // enumerable: true // }) delete obj.name Object.defineProperty(obj1, 'age', { value: 24, write: true, configurable: true, enumerable: true }) console.log(obj) console.log(obj1) // { name: "十一", age: 24 } console.log(Object.isExtensible(obj)) // false console.log(Object.isExtensible(obj1)) // true
code 3-5:Object.defineProperty() 之对象扩展
3.2 Object.defineProperties()
3.2.1 作用
在一个对象上定义多个新的属性汇总修改现有属性,并返回该对象
3.2.2 用法
其实就是defineProperty的集合版
var obj = { name: '十一' }
var h1Html = document.getElementById("H1");
Object.defineProperties(obj, {
age: {
value: 24,
writable: true,
configurable: true,
enumerable: true
},
h1Html: {
get: function(){
return h1Html.innerHTML;
},
set: function(val){
h1Html.innerHTML = val;
},
configurable: true,
enumerable: true
}
})
console.log(obj); // { name:'十一', age:24, h1Html: h1标签的内容}
code 3-6:Object.defineProperties() 用法
3.3 Object.getOwnPropertyDescriptor()
3.3.1 作用
获取一个对象上自身属性(获取不到原型链上的属性)的描述符,不存在则返回undefined
3.3.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(Object.getOwnPropertyDescriptor(obj,'age'))
// {value: 24, writable: true, enumerable: true, configurable: true}
console.log(Object.getOwnPropertyDescriptor(obj,'age1')) // undefined
code 3-7:Object.getOwnPropertyDescriptor() 用法
3.4 Object.getOwnPropertyDescriptors()
3.4.1 作用
获取一个对象上所有自身属性(获取不到原型链上的属性)的描述符
3.4.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(Object.getOwnPropertyDescriptor(obj))
// {
// age: {value: 24, writable: true, enumerable: true, configurable: true},
// h1Html: {get: ƒ, set: ƒ, enumerable: true, configurable: true},
// name: {value: "十一", writable: true, enumerable: true, configurable: true}
// }
code 3-8:Object.getOwnPropertyDescriptors() 用法
3.5 Object.getOwnPropertySymbols()
3.5.1 作用
返回一个数组,该数组包含了指定对象自身所有symbol属性键。
3.5.2 用法
var classRoom = {
[Symbol('lily')]: { grade: 60, sex: 'Woman' },
[Symbol('nina')]: { grade: 67, sex: 'Woman' },
[Symbol('nina')]: { grade: 80, sex: 'man' },
}
console.log(classRoom);
// {
// Symbol(lily): {grade: 60, sex: "Woman"},
// Symbol(nina): {grade: 67, sex: "Woman"},
// Symbol(nina): {grade: 80, sex: "man"}
// }
var races = Object.getOwnPropertySymbols(classRoom);
console.log(races); // [Symbol(lily), Symbol(nina), Symbol(nina)]
code 3-9:Object.getOwnPropertySymbols() 用法
4. Object 的静态方法
4.1 Object.keys()
4.1.1 作用
返回自身属性的一个数组,不包括原型链上的属性。
4.1.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(Object.keys(obj)); // ["name", "age", "h1Html"]
code 4-1:Object.keys() 用法
4.2 Object.values()
4.2.1 作用
返回自身属性值的一个数组,不包括原型链上的属性值。
4.2.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(Object.values(obj)); // ["十一", 24, h1标签的内容]
code 4-2:Object.values() 用法
4.3 Object.entries()
4.3.1 作用
返回带有属性和值的复合数组,不包括原型链上的。
4.3.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(Object.entries(obj));
// [
// ["name", "十一"],
// ["age", 24],
// ["h1Html", h1标签的内容]
// ]
code 4-3:Object.entries() 用法
4.4 Object.getOwnPropertyNames()
4.4.1 作用
和Object.keys一样,区别是可以得到不能进行枚举的属性。
4.4.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
Object.defineProperty(obj, 'sex', {
value: '男',
writable: true,
configurable: true,
enumerable: false
})
console.log(Object.getOwnPropertyNames(obj)); // ["name", "age", "h1Html", "sex"]
code 4-4:Object.getOwnPropertyNames() 用法
4.5 Object.assign()
4.5.1 作用
拷贝对象,只是浅拷贝不是深拷贝,且原型链上的属性不能拷贝、不能枚举的属性也不能拷贝。
4.5.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
var newObj = {}
Object.assign(newObj,obj)
console.log(newObj); // {name: "十一", age: 24, h1Html: h1标签的内容}
code 4-5:Object.assign() 用法
4.6 Object.create()
4.6.1 作用
以参数作为原型对象,返回创建的实例对象(与原型链继承类似)。
4.6.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
var newObj = Object.create(obj)
console.log(newObj,obj); // 原型链的方式进行继承
// {
// name: h1标签的内容,
// __proto__: {
// age: 24,
// h1Html: h1标签的内容,
// name: "十一"
// }
// }
code 4-6:Object.create() 用法
4.7 Object.is()
4.7.1 作用
确定两个值是否相同,就可以解决+0、-0,NaN比较的方式。
4.7.2 用法
console.log(+0 === -0); // true
console.log(Object.is(+0,-0)); // false
console.log(Object.is(NaN,NaN)); // true
code 4-7:Object.is() 用法
4.8 Object.getPrototypeOf()
4.8.1 作用
获取对象的原型对象。
4.8.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(Object.getPrototypeOf(obj)); // ==>Object.prototype
code 4-8:Object.getPrototypeOf() 用法
4.7 Object.setPrototypeOf()
4.9.1 作用
设置对象的原型对象。
4.9.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
Object.setPrototypeOf(obj, Array.prototype)
console.log(Object.getPrototypeOf(obj) === Array.prototype); // true
code 4-9:Object.setPrototypeOf() 用法
5. Object 的实例方法和属性
5.1 hasOwnProperty()
5.1.1 作用
判断每个属性是否为当前对象自身下的属性,还是来自原型对象下的属性
5.1.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(obj.hasOwnProperty('name')); // true
console.log(obj.hasOwnProperty('name1')); // false
code 5-1:Object 的实例方法 hasOwnProperty() 用法
5.2 isPrototypeOf()
5.2.1 作用
跟instanceof运算符用法类似,用来判断当前对象是否在指定的原型对象上
5.2.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(Object.prototype.isPrototypeOf(obj)); // true
console.log(Array.prototype.isPrototypeOf(obj)); // false
code 5-2:Object 的实例方法 isPrototypeOf() 用法
5.3 propertyIsEnumerable()
5.3.1 作用
hasOwnProperty()的加强版,除了具备hasOwnProperty()的功能外,还对能for…in枚举的属性返回true
5.3.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
Object.defineProperty(obj, 'sex', {
value: '男',
writable: true,
configurable: true,
enumerable: false
})
console.log(obj.hasOwnProperty('sex')); // true
console.log(obj.propertyIsEnumerable('sex')); // false
code 5-3 Object 的实例方法:propertyIsEnumerable() 用法
5.4 toString()
5.4.1 作用
返回当前对象对应的字符串形式
5.4.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(obj.toString()); // '[object Object]'
code 5-4:Object 的实例方法 toString() 用法
5.5 valueOf()
5.5.1 作用
返回当前对象对应的值
5.5.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(1 + obj); // '1[object Object]'
重写Object的valueOf方法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
// 重写Object的valueOf方法
Object.prototype.valueOf = function(){
return 2
}
console.log(1 + obj); // 3
code 5-5:Object 的实例方法 valueOf() 用法
注:对象参与计算时,先调用valueOf(),若返回值为对象则继续调用toString()方法
5.6 constructor
5.6.1 作用
constructor 属性返回对创建此对象的数组函数的引用。
5.6.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log(obj.constructor); // ƒ Object() { [native code] }
console.log(obj.constructor === Object); // true
code 5-6:Object 属性 constructor 的用法
6. 相关语法
6.1 in
6.1.1 作用
通过 in 语法来判断属性是否是该对象的属性。语法:‘属性’ in obj (查看属性是否是obj的属性)
6.1.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
console.log('name' in obj); // true
console.log('name1' in obj); // fasle
code 6-1:Object 相关语法 in
6.2 for…in
6.2.1 作用
遍历对象的属性(方法是一种特殊的属性),属性不能枚举(enumerable为false)的不可遍历
6.2.2 用法
// 借助“code 3-6:Object.defineProperties() 用法”代码测试
Object.defineProperty(obj, 'sex', {
value: '男',
writable: true,
configurable: true,
enumerable: false
})
for(var key in obj){
console.log(key); // name, age, h1Html
console.log(obj[key]); // '十一', 24, h1标签的内容
}
code 6-2:Object 相关语法 for...in