《JavaScript高级程序设计》总结(四)—— 对象的数据属性和访问器属性

228 阅读3分钟

对象我们都知道是什么,但是对象当我们想对对象做些限制,该怎么办呢,可以用对象的内置属性

内置属性——数据属性

Object.defineProperty()

mdn上是这么定义的: Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,

语法 obj.defineProperty(obj,prop,descriptor)

参数 1.obj:要执行操作的对象 2.prop:操作的对象需要定义或修改的属性的名称 3.descriptor:具体的操作内容 return 传递给函数的对象。

configurable

是否可以删除或者修改目标对象属性的特性(就是我们现在要说的这几个) 默认值为false,设置为true的时候可以被修改或删除, 一旦被设置为false,就不能再把它变为可配置的,这一点很重要

举个栗子

当首先设置为true的时候可以被删除

        var obj = {
            name:'clearlove'
        }

        Object.defineProperty(obj,'name',{
            configurable:true
        })
        //删除属性
        delete obj.name
        console.log(obj.name) //undefined

设置为false的时候不可以被删除

        var obj = {
            name:'clearlove'
        }

        Object.defineProperty(obj,'name',{
            configurable:false
        })
        //删除属性
        delete obj.name
        console.log(obj.name) //clearlove

当设置为true的时候可以被修改特性

        var obj = {
            name: 'clearlove'
        }
          Object.defineProperty(obj, "name", {
            writable: false,
            enumerable: true,
            configurable: true
        });
        //重新修改特性
        Object.defineProperty(obj, "name", {
            writable: true,
            enumerable: true,
            configurable: true
        });
        console.log(obj.name); //clearlove

当设置为false的时候不可以修改特性

        var obj = {
            name: 'clearlove'
        }
        //重新修改特性
        //重新修改特性
        Object.defineProperty(obj, "name", {
            writable: false,
            enumerable: false,
            configurable: false
        });

        Object.defineProperty(obj, "name", {
            writable: true,
            enumerable: true,
            configurable: false
        });
        console.log(obj.name); 

enumerable

是否可以被再次枚举(使用for...in或Object.keys())默认为fasle,设置为true可以被枚举;设置为false,不能被枚举

举个栗子

 var obj = {}
  
  // 第一种情况:enumerable设置为false,不能被枚举。
  Object.defineProperty(obj, "newKey", {
    value: "hello",
    writable: false,
    enumerable: false
  });
  // 枚举对象的属性
  for( var attr in obj ){
    console.log( attr );  // undefined
  }
  
  // 第二种情况:enumerable设置为true,可以被枚举。
  Object.defineProperty(obj, "newKey", {
    value: "hello",
    writable: false,
    enumerable: true
  });
  // 枚举对象的属性
  for( var attr in obj ){
  console.log( attr );  //newKey
  }

value

对应属性的值

        var obj = {
            name: 'clearlove'
        }
        //重新修改特性
        //重新修改特性
        Object.defineProperty(obj, "name", {
           value:'Meiko'
        });
        console.log(obj.name); //Meiko

Wrirable

属性值是否可以被修改,默认为false

设置为false,不能被修改

        var obj = {
            name: 'clearlove'
        }
        Object.defineProperty(obj, "name", {
           writable:false
        });
        //修改name的值
        obj.name = 'Meiko'
        console.log(obj.name); //clearlove

设置为true可以被修改

        var obj = {
            name: 'clearlove'
        }
        Object.defineProperty(obj, "name", {
           writable:true
        });
        //修改name的值
        obj.name = 'Meiko'
        console.log(obj.name); //Meiko

关于默认值

在使用Object.defineProperty时,三个属性默认都为fasle,当不使用时默认都是为true

访问器属性

重点来说说get和set

get

在属性值被获取的时候进行的操作

        var obj = {
            name: 'clearlove'
        }
        Object.defineProperty(obj,'name',{
            //在属性被读取时,执行的操作
            get:function(){
                console.log('我被读取了')
                //return value
            }
        })

        console.log(obj.name) //我被读取了

在属性设置时进行的操作

        //在非严格模式下只设置set会打印undefined
        var obj = {
            name: 'clearlove'
        }
        Object.defineProperty(obj,'name',{
            //在属性被读取时,执行的操作
            set:function(){
                console.log('我被修改了')
                return value
            }
        })
        obj.name = 'Meiko'
        console.log(obj.name) 

基于上述特性我们是否可以做一个类似vue计算属性的东西呢

举个栗子

    //根据年龄计算出生日期
        //1.获取现在的年份
        var myDate = new Date();
        var tYear = myDate.getFullYear();
        //2.新建对象赋予年份
        var obj = {
            nowyear:tYear,
            _oldyear:22,
            birthdyear:0
        }
        //3.输入年龄计算,根据年龄出生年
        Object.defineProperty(obj,'oldyear',{
            get:function(){
                return this._oldyear
            },
            set:function(newValue){
                this._oldyear = newValue
                this.birthdyear = this.nowyear - newValue 
            }
        })

        //设置oldyear的值,得到出生年
        obj.oldyear = 25
        console.log(obj.birthdyear)//1994