对象(回顾)

概念

通常属性和对应属性的值是以键值对(key:value)的形式显示的变量。此外,对象中可以放入函数,放在对象中的函数也可以叫做方法

  1. 以键值对(key:value)来描述一个对象的特展
  2. {key:value,…} 每组键值对是 key:value 的格式,多组键值对用逗号分割
  3. key 不能是引用类型,value可以是任何的数据类型

创建对象的3种方法

方式1:对象字面量 { }

var obj = {};

方式2:对象构造函数

new Object(); // {}

方式3:Object.create

Object.create(null);// {}

基本操作

获取(查)

方式1 属性访问:对象.属性名

方式2 键访问:对象[属性名]
注意:此方式可以放变量,且对象内部的 key 不区分StringNumber

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)
    })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳晓黑胡椒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值