对象的拓展

别来无恙 提交于 2020-04-05 23:29:29

对象拓展

对象拓展回顾: 对象字面量,对象解构,三个点运算符

对象name属性

对象的方法name属性,但是有两种属性方法比较特殊。 1、如果是特性方法,要通过特性对象获取。

// // 对象
// let obj = {
//     demo() {},
//     // 特性方法
//     get num() {},
//     set num(val) {
//         return 10
//     },
// }
// console.log(obj.demo.name)
// // 特性方法名称
// // console.log(obj.num.name) //报错
// // 通过特性对象获取
// let descriptor = Object.getOwnPropertyDescriptor(obj, 'num');
// console.log(descriptor)
// console.log(descriptor.get.name)
// console.log(descriptor.set.name)

2、如果是symbol属性方法,返回symbol描述。

// // Symbol数据
// let s1 = Symbol('ickt')
// let s2 = Symbol()
// // 对象
// let obj = {
//     demo() {},
//     // 特性方法
//     get num() {},
//     set num(val) {
//         return 10
//     },
//     [s1]() {},
//     [s2]() {}
// }
// console.log(obj.demo.name)
// // Symbol属性方法
// console.log(obj[s1].name)
// console.log(obj[s2].name)

Null传导运算符

用来判断属性或者方法是否存在,存在返回或者执行,有四种用法。

// null传导
// let obj = {};
// let s1 = Symbol();
// let obj = {
//     a: {
//         b: {
//             c() {
//                 return {
//                     d: 100,
//                     [s1]: 20
//                 }
//             }
//         }
//     }
// };
// ?.避免与?:混淆
// console.log(obj.a && obj.a.b && obj.a.b.c && obj.a.b.c() && obj.a.b.c().d)
// console.log(obj?.a?.b?.c()?.d)
// console.log(obj?.a?.b?.c()?.[s1])
// delete obj?.a?.b.c;
// console.log(obj)
// 赋值暂不支持
// obj?.x?.y.z = 10

对象的静态方法

Object.is

该方法的有两个作用:1、判断+0和-0 2、判断NaN

// 代替===
// console.log(Object.is())
// 000000000    100000000
// console.log(+0/1 === -0/1)
// console.log(Object.is(+0/1, -0/1))
// console.log(Object.is(0/0, +'abc'))

Object.assign

是为对象拓展一个静态方法,实现对参数对象的复制(多继承),实现的浅复制 浅复制:值类型数据直接复制,引用类型的数据直接改变指向(引用同一个) 深复制:值类型数据直接复制,引用类型的数据(不包括函数)直接复制复制 jquery的extend方法可以实现深复制,将第一个参数传递为布尔值true

// 复制 
let obj1 = {
    color: 'red',
    num: 10
}
let obj2 = {
    color: 'green',
    size: {
        width: 10,
        height: 20
    }
}
let obj3 = {
    num: 20,
    arr: [1, 2, 3]
}
// 定义特性
Object.defineProperty(obj3, 'msg', {
    value: 'hello',
    enumerable: false
})
// 复制 
Object.assign(obj1, obj2, obj3);
// 浅复制
// $.extend(obj1, obj2, obj3);
// // 深复制
// $.extend(true, obj1, obj2, obj3);
// // 修改obj2
// obj2.color = 'blue';
// obj2.size.width = 100;
// console.log(obj1)
// console.log(obj3)

第一个参数不能是null或undefined,其它非对象类型参数将包装成对象(虽然number和布尔值无意义)

// console.log(Object.assign(null))
// console.log(Object.assign(undefined))
// console.log(Object.assign('hello'))
// console.log(Object('hello'))
// console.log(Object.assign(100))
// console.log(Object(100))
// console.log(Object.assign(true))
// console.log(Object(true))
// // 转换数组
// console.log(Object.assign([5, 6, 7], [1, 2]))

只能合并枚举的属性

// 复制 
let obj1 = {
    color: 'red',
    num: 10
}
let obj2 = {
    color: 'green',
    size: {
        width: 10,
        height: 20
    }
}
let obj3 = {
    num: 20,
    arr: [1, 2, 3]
}
// 定义特性
Object.defineProperty(obj3, 'msg', {
    value: 'hello',
    enumerable: false
})
// 复制 
Object.assign(obj1, obj2, obj3);
console.log(obj1)
console.log(obj3)

用途;复制对象,合并对象,定义默认配置,为对象拓展实例属性,拓展原型方法等

// function Player(name, x, y) {
function Player(options) {
    // this.name = name;
    // this.x = x;
    // this.y = y;
    Object.assign(this, options)
}
// 拓展原型
Object.assign(Player.prototype, {
    demo() {}
})
console.log(new Player({
    name: 'ickt',
    x: 10,
    y: 20
}))

对象__proto__与对象遍历

__proto__属性用来获取实例对象继承的原型对象 Object.setPrototypeOf() 用来设置对象的原型 Object.getPrototypeOf() 用来获取对象的原型 遍历方法: Object.keys: 返回一个数组,成员是参数对象自身(不含继承的)所有可遍历的属性的键名。 Object.values:返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历的属性值。 Object.entries:返回一个数字,成员是参数对象自身的(不含继承的)所有可遍历的属性的键值对

        let obj = {
            num: 10,
            color: 'red'
        }
        //设置特性
        // 特性
        Object.defineProperties(obj, {
            width: {
                value: 100,
                enumerable: true
            },
            height: {
                value: 200,
                enumerable: false
            }
        })
        // 获取属性
console.log(Object.keys(obj))
console.log(Object.values(obj))
console.log(Object.entries(obj))
Object.keys(obj).forEach(key => console.log(key, obj[key]))
Object.entries(obj).forEach(arr => console.log(...arr))

数组。 属性的遍历: 属性是否可以枚举,用特性enumerable来说明。 Object.getOwnPropertyDescriptorss: ES2017引入新的方法,返回指定对象所有自身属性(非继承属性)的描述对象

// 获取特性
console.log(Object.getOwnPropertyDescriptor(obj,"width"))
console.log(Object.getOwnPropertyDescriptors(obj))

对象遍历的方式

遍历对象属性有五种方式 1、 for in 循环 2、 Object.keys() 、Object.values() 、 Object.enteries() 3、 Object.getOwnProertyNames() 4、 Object.getOwnPropertySymbols() 5、 Reflect.ownKeys()

//遍历对象属性
// symbol数据
let s1 = Symbol('ickt');
let s2 = Symbol('hello');
// 对象
let obj = {
    num: 10,
    color: 'red',
    [s2]: 30,
    [s1]: 20,
    5: 20,
    1: 10
}
Object.setPrototypeOf(obj, {
    msg: 'hello'
})
// 特性
Object.defineProperties(obj, {
    width: {
        value: 100,
        enumerable: true
    },
    height: {
        value: 200,
        enumerable: false
    }
})  
// 1 for in循环: 可以遍历:对象自身,原型,可枚举的,   不能遍历:symbol, 不可以枚举的    
// for(let key in obj){
//     console.log(key)
// }
// 2 Object. keys()、 Object.values()、 Object.entries()
// 可以遍历:对象自身,可枚举的,   不能遍历:symbol, 不可以枚举的,原型,
// console.log(Object.keys(obj))
// 3 Object.getOwnPropertyNames()
// 可以遍历:对象自身,可枚举的, 不可以枚举的   不能遍历:symbol,原型,
// console.log(Object.getOwnPropertyNames(obj))
// 4 Object.getOwnPropertySymbols()
// 可以遍历:symbol,   不能遍历:原型,对象自身,可枚举的, 不可以枚举的
// console.log(Object.getOwnPropertySymbols(obj))
// 5 Reflect.ownKeys()
// 可以遍历:symbol,对象自身,可枚举的, 不可以枚举的   不能遍历:原型,
console.log(Reflect.ownKeys(obj))

遍历属性顺序 数字类型:按照数字大小顺序。 字符串类型:添加时间顺序。 Symbol类型:添加时间顺序

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!