美文网首页
前端学习笔记:Object常用方法(一)

前端学习笔记:Object常用方法(一)

作者: 网恋被骗二块二 | 来源:发表于2021-12-07 18:07 被阅读0次

Object.defineProperty()

三个参数:监听的对象(obj),属性名(key),属性描述(descriptor )

先理解第三个参数(参数类型:object)

writable :默认false(只读),true为可编辑

        let obj = {}
        Object.defineProperty(obj, "name", {
            value: '张三'
        })
        console.log(obj.name)  // 张三
        obj.name = '王老五'
        console.log(obj.name)  // 张三
        let obj = {}
        Object.defineProperty(obj, "name", {
            value: '张三',
            writable: true
        })
        console.log(obj.name)  // 张三
        obj.name = '王老五'
        console.log(obj.name)  // 王老五

enumerable :是否可以被枚举,也就是遍历和使用Object.keys()时能否读取到这个属性值。默认为false(不可枚举),不影响该属性的正常使用和读取。

        let obj = {
            age: 18,
            info: '哈哈'
        }
        Object.defineProperty(obj, "name", {
            value: '张三',
        })
        let key = Object.keys(obj)
        console.log(key)  // ['age', 'info']
        console.log(obj.name)  // 张三
        let obj = {
            age: 18,
            info: '哈哈'
        }
        Object.defineProperty(obj, "name", {
            value: '张三',
        })
        let key = Object.keys(obj)
        console.log(key)  //  ['age', 'info', 'name']
        console.log(obj.name)  // 张三

configurable :是否可以被删除和重新定义特性,默认为false(禁止)

        let obj = {}
        Object.defineProperty(obj, "name", {
            value: '张三',
            writable: true,
            configurable: false
        })
        console.log(obj.name) //  张三
        delete obj.name
        console.log(obj.name) //  张三
        //结果还在,不可被删除
        Object.defineProperty(obj, 'name', {
            value: 'Jack',
            enumerable: true
        })
        // 当你写到这儿的时候,控制台报错 :Uncaught TypeError: Cannot redefine property: name
        // 无法重新定义name这个属性
        // 所以此时需要把前面定义过的configurable的值改为true

set : 当你在设置这个对象属性的值时,会被调用,自带一个参数,参数的来源是给对象属性赋予的值。默认是undefined(没有),若使用则需要自行定义。

        let obj = {}
        Object.defineProperty(obj, "name", {
            set(newVal) {
                this.info = newVal
            }
        })
        console.log(`name:${obj.name},info:${obj.info}`) name:undefined,info:undefined
        obj.name = "张三大魔王"
        console.log(`name:${obj.name},info:${obj.info}`) name:undefined,info:张三大魔王

注意点:
1.不能和value和writable同用(未捕获的类型错误:无效的属性描述符。 不能同时指定访问器和值或可写属性)
2.赋值对象不能是第二参数

        let obj = {}
        Object.defineProperty(obj, "name", {
            set(newVal) {
                this.name = newVal
            }
        })
        obj.name = "张三大魔王"
       // Uncaught RangeError: Maximum call stack size exceeded
       // 超出最大调用堆栈大小
       // 百度了解后,意思是obj.name = '' 调用了set方法,set方法里this.name = newVal转换
       // 后也就等价于obj.name = newVal,那么进行了赋值操作此时又要调用set方法,由此形成
       // 一个回调上的死循环

get 当读取对象属性的值时调用,通过return返回内容,可以返回任意类型

        let obj = {
            name: 'zs'
        }
        console.log(obj.name)  //  zs
        Object.defineProperty(obj, "name", {
            get() {
                return 2
            }
        })
        console.log(obj.name)  // 2

注意点:
1.与set一样不能和writable以及value同时出现
2.由例子中看出,可以改变它之后的对象属性的读取内容

第二个参数(参数类型:string)

可以是新增属性,也可以直接对已有属性进行编辑

第一个参数

只能是一个对象,不能写null
这里像Math、Array、Date等都属于Object对象,也是可以作为参数使用

        let arr = [1, 2, 3]
        Object.defineProperty(Math, 'info', {
            value: 32
        })
        Object.defineProperty(arr, 'info', {
            value: 32
        })
        console.log(Math.info)  // 32
        console.log(arr.info) // 32

Object.defineProperties()

个人理解是Object.defineProperty()的复合写法,可一次性对多个属性进行批量操作。

        let obj = {
            name: 'zs'
        }
        console.log(obj.name)  // zs
        Object.defineProperties(obj, {
            'name': {
                value: 22,
                writable: true
            },
            'info': {
                get() {
                    return 'sorry'
                }
            },
            'age': {
                set(newVal) {
                    this.blue = newVal
                }
            }
        })
        console.log(obj.name)  // 22
        console.log(obj.info)  //  sorry
        obj.age = 19
        console.log(obj.age, obj.blue) // undefined 19

Object.create()

使用指定原型对象及其属性去创建一个新对象
什么意思呢?先看这个方法有几个参数:
第一个参数:指定新对象的原型对象,可以为null,也可以普通对象或某个构造函数的原型对象,但不能不写。
第二个参数:给新对象的赋予属性,写法和defineProperties的复合写法一样。

        let obj = {
            name: 'zs'
        }
        console.log(obj.__proto__)  // 指向Object的原型对象
        let newObj = Object.create(null, {
            a: {
                value: '我是A'
            },
            b: {
                set(newVal) {
                    this.info = '我是由B赋值的'
                }
            }
        })
        newObj.b = '我是B'
        console.log(newObj.a, newObj.b, newObj.info) // 我是A undefined 我是由B赋值的
        console.log(newObj.__proto__)  // undefined

由这个例子可以看出这个使用create创建的新对象的原型对象是需要人为指定的。

// 此时将第一个参数更换一下试试呢?
var newObj = Object.create(Object.prototype)
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
var newObj = Object.create(Object)
// Object() { [native code] }
var newObj = Object.create({name:'zs'})
// {name: 'zs'}

可以看出这个create方法比较重要的是第一个参数,第二个参数可以为空,之后添加新属性就和平时对对象的操作一样,也可以使用前两个。

Object.keys(object) 和 Object.values(object)

返回一个对象所有属性的数组/返回一个对象所有属性值的数组

        let obj = {
            name: 'zs',
            age: 17
        }
        Object.defineProperty(obj, 'info', {
            value: 32
        })
        let keys = Object.keys(obj)
        let val = Object.values(obj)
        console.log(keys, val) //  ['name', 'age']      ['zs', 17]
        console.log(obj)  //  {name: 'zs', age: 17, info: 32}

注意,通过defineProperty、defineProperties、和create第二个参数,创建的属性,如果不设置enumerable属性,那么keys和values都将获取不到。

Object.entries()

keys()和values()的合并版

        let obj = {
            name: 'zs',
            age: 18,
            info: '我是对象'
        }
        let kv = Object.entries(obj)
        console.log(kv)
// [['name', 'zs'],['age', 18],['info', '我是对象']]
// 不能获取enumerable:false的属性

Object.assign()

对象的合并,一个主参数,和其他被合并的对象。

        let obj = {
            name: 'zs',
            age: 17
        }
        let obj2 = {
            info: '我是第二个对象'
        }
        Object.assign(obj, obj2)
        console.log(obj)  // {name: 'zs', age: 17, info: '我是第二个对象'}
        let obj = {
            name: 'zs',
            age: 17
        }
        let arr = [
            [1, 1, 1], 2, 3
        ]
        Object.assign(obj, arr)
        console.log(obj)   //  {0: Array(3), 1: 2, 2: 3, name: 'zs', age: 17}

以数组为参数时,把数组的下标作为属性名,元素作为值。
拷贝时如果有重复的属性,后面的把前面的覆盖。
应用场景:

        let box = document.querySelector('div')
        Object.assign(box.style, {
            width: '100px',
            height: '100px',
            background: 'skyblue'
        })
        // style也是一个属性,所以也可以用此方法快速赋值,节省重复的代码
image.png

hasOwnProperty(key)

判断对象中有无该属性,有则返回true,反之false

obj.hasOwnProperty('name') // true
//注意参数必须是字符串或者赋值后的变量

(未完待续……)
目前根据学习程度,代码中使用频率较高的只总结到这个地步,若往后有用到的再补充。
有兴趣的可以点击下方链接继续深度学习。

相关文章

网友评论

      本文标题:前端学习笔记:Object常用方法(一)

      本文链接:https://www.haomeiwen.com/subject/aevgxrtx.html