概念
通常属性和对应属性的值是以键值对
(key:value)的形式显示的变量。此外,对象中可以放入函数,放在对象中的函数也可以叫做方法
- 以键值对(key:value)来描述一个对象的特展
- {key:value,…} 每组键值对是 key:value 的格式,多组键值对用逗号分割
- key 不能是引用类型,value可以是任何的数据类型
创建对象的3种方法
方式1:对象字面量 { }
var obj = {};
方式2:对象构造函数
new Object(); // {}
方式3:Object.create
Object.create(null);// {}
基本操作
获取(查)
方式1 属性访问:对象
.属性名
方式2 键访问:对象
[属性名]
注意:此方式可以放变量,且对象内部的 key 不区分String
和Number
let obj = {1: 2}
console.log(obj[1]);//2
console.log(obj['1'])//2
方式3:Object.keys Object.values Object.entries
let obj = {a:1,b:2,c:4}
console.log(Object.keys(obj));//[ 'a', 'b', 'c' ]
console.log(Object.values(obj));//[ 1, 2, 4 ]
console.log(Object.entries(obj));//[ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 4 ] ]
方式4:for…in
增
对象名.新添属性名=“属性值”;
删
删除必须引用操作符 delete
delete obj.num;// true
对象中的属性分类
对象有数据属性
和访问器属性
属性描述符
configurable
可配置性
,默认为 true
表示是否通过delete删除属性从而重新定义属性,能否修改属性的特性
enumerable
可枚举性
,默认为true
表示能否通过for-in循环,对下给你属性是否展示
writable
可写性
,默认为true
表示能否修改值(value)
value
其属性值
访问器标记
Get
取值函数
Set
赋值函数
对象属性方法
Object.getOwnPropertyNames
(obj)
定义:返回一个由指定对象的所有自身属性的属性名
(包括不可枚举属性
但不包括符号值作为名称的属性)组成的数组
参数1:指定对象
let obj = {a: 1, b: 2, c: 4}
Object.defineProperty(obj, "d", {
writable: true,
enumerable: false,
configurable: false,
value: 5
})
let res = Object.getOwnPropertyNames(obj);//[ 'a', 'b', 'c', 'd' ]
console.log(obj);//{ a: 1, b: 2, c: 4 }
Object.getOwnPropertyDescriptor
(obj,prop)
定义:指定属性性存在于对象上,则返回其属性定义对象
(属性描述符),否则返回 undefined
参数1:需要查找的目标对象
参数2:目标对象内属性名称
let obj = {a: 1, b: 2, c: 4}
let res = Object.getOwnPropertyDescriptor(obj, "a");
console.log(res)//{ value: 1, writable: true, enumerable: true, configurable: true }
Object.getOwnPropertyDescriptors
(obj)
定义:用来获取一个对象的所有自身属性描述符
参数1:需要查找的目标对象
let obj = {a: 1, b: 2, c: 4}
Object.defineProperty(obj, "d", {
writable: true,
enumerable: false,
configurable: false,
value: 5
})
let res = Object.getOwnPropertyDescriptors(obj, "a")
console.log(res);
//{
// a: { value: 1, writable: true, enumerable: true, configurable: true },
// b: { value: 2, writable: true, enumerable: true, configurable: true },
// c: { value: 4, writable: true, enumerable: true, configurable: true },
// d: { value: 5, writable: true, enumerable: false, configurable: false }
//}
console.log(obj);//{ a: 1, b: 2, c: 4 }
Object.defineProperty
(obj, prop, descriptor)
定义:在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象
let obj = {a: 1, b: 2, c: 4}
let res = Object.defineProperty(obj, "d", {
writable: true,
enumerable: false,
configurable: false,
value: 5
})
console.log(res);//{ a: 1, b: 2, c: 4 }
console.log(obj);//{ a: 1, b: 2, c: 4 }
Object.defineProperties
(obj,props)
定义:一个对象上定义新的属性或修改现有属性,并返回该对象
let obj = {a: 1, b: 2, c: 4}
Object.defineProperty(obj, "d", {
writable: false,
enumerable: false,
configurable: true, // 如果不可配置,修改对象描述符则会保存
value: 5
})
let res = Object.defineProperties(obj, {
c: {
enumerable: true,
value: 5
},
d: {
value: 7,
writable: true,
enumerable: true,
configurable: false,
}
})
console.log(res);//{ a: 1, b: 2, c: 5, d: 7 }
console.log(obj);//{ a: 1, b: 2, c: 5, d: 7 }
关于对象的规则设置
创建一个常量
结合
writable
:false 和configurable
:false 就可以创建一个真正的常量属性
冻结
Object.freeze(obj)
定义:冻结
一个对象,使其只读,即使不可扩展的,也是密封的
被冻结的对象:
- 不能修改成员的值
- 不能新增成员
- 不能删除现有成员
- 不能给成员做劫持(Object.defineProperty)
let obj = {a: 1, b: 2, c: 4}
Object.freeze(obj)
obj.d = 5
obj.a = 2
console.log(obj);// {a: 1, b: 2, c: 4}
Object.isFreezee(obj)
定义:确定对象是否冻结,返回布尔值
let obj = {a: 1, b: 2, c: 4}
Object.freeze(obj)
console.log(Object.isFrozen(obj));// true
密封
Object.seal(obj)
定义:密封
一个对象,也是不可扩展的
被密封的对象:
- 可以修改成员的值
- 不能新增成员
- 不能删除现有成员
- 不能给成员做劫持(Object.defineProperty)
let obj = {a: 1, b: 2, c: 4}
Object.seal(obj)
obj.d = 5
obj.a = 2
delete obj.a
console.log(obj);// { a: 2, b: 2, c: 4 }
Object.isSealed(obj)
定义:确定对象是否密封,返回布尔值
let obj = {a: 1, b: 2, c: 4}
Object.seal(obj)
console.log(Object.isSealed(obj));// true
扩展
Object.preventExtensions(obj)
定义:一个对象被设置成不可扩展
对象
不可扩展的对象:
- 可以修改成员的值
不能新增
成员- 可以删除现有成员
- 可以给成员做劫持(Object.defineProperty)
let obj = {a: 1, b: 2, c: 4}
Object.preventExtensions(obj)
obj.d = 5
obj.a = 2
delete obj.a
console.log(obj);// { b: 2, c: 4 }
Object.isExtensible(obj)
定义:确定对象是否扩展,返回布尔值
let obj = {a: 1, b: 2, c: 4}
Object.preventExtensions(obj)
console.log(Object.isExtensible(obj));// false 不可扩展
对象的枚举
for…in
定义:查看对象的枚举
- 注意:
- 不建议用在数组上面,虽然有效
- 遍历时,是优先按照从
小到大的机制遍历数组属性
- 既可以迭代
私有
的,也可以迭代共有
的- 只能迭代
可枚举
,非Symbol类型
的属性
const obj = {
a: 1, b: 2, c: 3, 2: 4, 1: 5
};
for (let key in obj) {
console.log(key)// 1 2 a b c
}
- 对于
稀松数组
,for…in循环不到任何东西
const arr=new Array(1000);
for (let key in arr) {
console.log(key);// 未执行
}
obj.hasOwnProperty(prop)
定义:指示对象自身属性中是否具有指定属性
,返回布尔值
Object.prototype.d = 2
var obj = {
a: 1, b: 2, c: 3
};
console.log(obj.hasOwnProperty("a"));// true
console.log(obj.d);// 2
console.log(obj.hasOwnProperty("d"));// false
判断访问操作符
定义:如果指定属性
在指定的对象或其原型链中,则 in 运算符返回 true
Object.prototype.d = 2
var obj = {
a: 1, b: 2, c: 3
};
console.log("a" in obj);//true
console.log("d" in obj);//true
console.log("e" in obj);//false
instanceof
定义:检测构造函数的 prototype 属性是否出现在某个实例对象的原型链
上
function Person(){}
const p = new Person()
console.log(p in Person);//false
console.log(p instanceof Person);//true
console.log(Person instanceof Function);//true
console.log(p instanceof Object);//true
console.log(p instanceof Array);//fasle
区别数组和对象的4种方法
- constructor 构造器
const arr = []
const obj = {}
console.log(arr.constructor);//[Function: Array]
console.log(obj.constructor);//[Function: Object]
- instanceof
const arr = []
const obj = {}
console.log(arr instanceof Array);//true
console.log(obj instanceof Array);//false
- 调用 Object.toString 方法
const arr = []
const obj = {}
console.log(Object.prototype.toString.call(arr));//'[object Array]'
console.log(Object.prototype.toString.call(obj));//'[object Object]'
console.log({}.toString.call(arr));//'[object Array]'
console.log({}.toString.call(obj));//'[object Object]'
- Array.isArray(obj)
const arr = []
const obj = {}
console.log(Array.isArray(arr));//true
console.log(Array.isArray(obj));//false
封装一个对象迭代的方法
需求:基于传统的 for/in 循环,会存在一些弊端
「
性能较差
;既可以迭代私有的,也可以迭代共有的;只能迭代"可枚举,非Symbol类型的属性…"」.
解决思路:
Object.getOwnPropertyNames(arr) -> 获取对象非Symbol类型的私有属性「无关是否可枚举」
Object.getOwnPropertySymbols(arr) -> 获取对象Symbol类型的私有属性
也可以基于ES6的Reflect.ownKeys 代替上述操作「弊端:不兼容IE」
const each = function (obj, callback) {
if (obj === null || typeof obj !== 'object') return obj
if (typeof callback !== 'function') return
let keys = Reflect.ownKeys(obj);
/* 兼容IE */
/*let keys = Object.getOwnPropertyNames(arr).concat(Object.getOwnPropertySymbols(arr))*/
keys.forEach(key => {
let value = obj[key]
// 每一次迭代,都把回调函数执行
callback(value, key)
})
}