ES5标准中的Object.create() 和 Object.defineProperties()

ES5标准中的Object.create() 和 Object.defineProperties()

JohnKeatinghhh

ES5标准中的Object.create和Object.defineProperties

 

Object.create(prototye,[description])

【作用】:以指定对象为原型,创建新的对象
【参数】:

  • prototype: 就是要作为原型的那个对象;
  • description 为新的对象指定新的属性,并对属性进行描述,可用的关键字:
    – value:新属性的值
    – writable: 是否可以修改,默认false
    – configurable: 是否可以删除,默认false
    – enumerable: 当前属性是否可以被for… in… 枚举到,默认false
    – get:属于accessors的一种,值是获取当前属性指的回调函数 (注意accessors与 valuewritable这两个冲突,逻辑上也很好理解)
    – set:属于accessors的一种,值是修改当前属性值触发的回调函数,并且实参即为修改后的值 (注意accessors与 valuewritable这两个冲突,逻辑上也很好理解)

【栗子】:

        var obj = {
            country : 'CN',
            race : 'HUM'
        }
        var new_obj = Object.create(obj,{// 最外层对象,键是要创建的新属性名称,值是一个对象,包括了value,writable等属性
            name:{
                value:'蔡徐坤',
                enumerable:true
            },
            gender:{
                value:'女',
                writable:true, //可以修改性别
                configurable:true, //可以不要性别
                enumerable:false //不要暴露自己的性别
            }
        })
        new_obj.name = 'ikun' //名字改不了
        new_obj.gender = '男' //厉不厉害你鲲哥
        for(var i in new_obj){
            console.log(new_obj[i])
        }

上面这个例子以我国著名音乐家、舞蹈家、篮球运动员蔡徐坤先生为例。

首先设置一个obj父类,包含了country属性和race属性,然后通过调用Object方法,以obj为原型构造一个新的对象new_obj,并定义两个新的属性:namegender,而 这两个属性也分别是两个对象,对象中包括了一些性质:
其中namewritableconfigurable默认是false,颇有行不更名坐不改姓的高风亮节;
genderwritableconfigurable则设为true,展现了她艺术人格中灵活多变的一面。

定义完new_obj之后,尝试修改姓名为'ikun',由于她行不更名坐不改姓的艺术风骨,这个改动失败了。
new_obj.gender = '男'则展现了性别的灵活多变,令人目不暇接。

最后通过for枚举new_obj的属性,会打印出name,countryage,唯独将gender神秘的一面留给了大家。(因为enumerable是false)

Object.defineProperties(object,descriptors)

【作用】:为指定对象扩展多个属性
【参数】:

  • object: 要扩展属性的对象;
  • descriptors 要扩展的属性,并对属性进行描述,可用的关键字:
    – value:新属性的值
    – writable: 是否可以修改,默认false
    – configurable: 是否可以删除,默认false
    – enumerable: 当前属性是否可以被for… in… 枚举到,默认false
    – get:属于accessors的一种,值是获取当前属性指的回调函数 (注意 accessors与 valuewritable这两个冲突,逻辑上也很好理解)
    – set:属于accessors的一种,值是修改当前属性值触发的回调函数,并且实参即为修改后的值 (注意 accessors与 valuewritable这两个冲突,逻辑上也很好理解)

【栗子】:

由于上一个例子演示了value和writable,这个例子就演示下get 和 set。
value/writable和 get/set是冲突的两组属性。
如果属性A设置了value/writable,那么这个属性A的属性可以直接通过obj.A访问,但是这样定义属性会有一个不方便的地方,那就是需要用到对象中其他属性的时候:
假设这样一个情景,一个对象的fullName属性需要通过firstNamelastName拼接而成,那么在定义的时候可能会写出这样的错误代码:

        var obj3 = {
            firstName : 'kobe',
            lastName : 'bryant',
            fullName : this.firstName + this.lastName
        }
        console.log(obj3)

最后的结果,obj3的fullName属性是NaN,为什么?
因为定义这个对象的时候,this指向的是window作用域,window里自然是没有firstNamelastName的,而我们用Object.defineProperties则可以解决这个问题:

        var obj2 = {
            firstName: 'kobe',
            lastName: 'bryant'
        }
        Object.defineProperties(obj2, { // 最外层对象,囊括要设置的属性
            fullName: {
                get: function () { //获取扩展属性的回调函数
                    return this.firstName + ' ' + this.lastName
                },
                set: function (data) { //监听扩展属性的回调函数,当扩展的属性发生变化时会自动调用
                    //此时扩展的属性的新值会作为实参传入到这个回调函数中
                    dataArr = data.split(' ')
                    this.firstName = dataArr[0]
                    this.lastName = dataArr[1]
                },
                // value: 'shabi',
                // writable: true,
                // configurable:true,
                enumerable: true
            }
        })
        obj2.fullName = 'steve jobs'
        for (var i in obj2) {
            console.log(obj2[i])  // steve jobs
        }

通过get属性绑定一个回调函数,来获取fullName属性。可能大家会有个疑问:为什么get回调函数里的this就指向obj2本身呢?这个就是get 底层的逻辑了。这个get实际上是一个异步的过程,每当 fullName成为右值的时候,get就会被调用。

同理,set通过绑定一个回调函数来监听 fullName的变化。每当fullName成为左值的时候,set方法就会别调用,并且会将赋给左值的东西(这个案例里是'steve jobs'字符串)作为实参(对应的形参就是data)传入到set函数中。在set函数里通过分割字符串分别修改firstNamelastName,这样下次再获取fullName的时候,就能根据新的firstNamelastName计算出新的fullName,也就是实现了对fullName的更新。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值