Object.definedProperty定义对象的属性

333 阅读3分钟

引言

es5以及之前版本的ECMAScript是没有类(对某些抽象的类型的属性和方法的封装)的概念的,不像java一些语言中,要先声明一个类再去new出这个对象. 在es5中使用构造函数(原则上也是一种函数)实现了对属性和方法的封装,更方便去定义相似的实实例的

对象的创建方式

通过new Object函数的方式创建

var person=new Object()
person.name='jack';
person.sayName=function(){    
    alert(this.name)
}

字面量创建方式


   var person={
       name : 'jack',
       sayName : function(){
        alert(this.name)
      }
   }

设置类之后通过new创建方法

引言

但是设想一下如果现在有一个班级要求创建出班级所有学生对象并包含一些他们的基本信息(姓名,年龄...)和一些共同的行为(上课,考试...), 如果这时候一个一个的用字面量去创建那不是太麻烦了 所以这时候最好的办法就是创建一个构造函数,里面包含需要的属性(姓名,年龄...),和一些共同的方法(上课,考试...)

实现
 function Student(name,age){
    this.name=name;
    this.age=age;
}
Student.prototype.test=function(){
    alert('kaoshi')
}

对象中的属性类型

数据属性

数据属性拥有四个描述其行为的特性

  • Configurable
  • Enumerable
  • Writable
  • Value
特性 含义 默认值
Configurable 能否通过delete删除属性,能否修改属性的特性,能否把属性改为访问器属性 true
Configurable 能否通过delete删除属性,能否修改属性的特性,能否把属性改为访问器属性 true
Enumerable 能否通过for-in循环返回属性 true
Writable 能否修改属性值 true
Value 代表属性值 undefined

Object.defineProperty修改属性默认的特性

Object.defineProperty(属性对象,属性名,{
    (要修改的特性一个或多个)
    Writable:false,
    value:'jack'
})

把对象的某一属性值设置成不可写,再改变的话,非严格模式下忽略,严格模式下报错

Object.defineProperty(属性对象,属性名,{
    (要修改的特性一个或多个)
    Configurable:false,
    value:'jack'
})

一旦把属性定义为不可配置的就不能把它在定义成可配置的了 并且不能delete这个属性了,否则非严格模式下忽略,严格模式下报错 并且再调用 defineProperty 修改除Writable之外的特性都会报错

总之就是把Configurable设置成false后就不要删除这个属性或者再修改它的相关配置了

访问器属性

访问器属性的四个特性

  • Configurable
  • Enumerable
  • Get
  • Set
特性 含义 默认值
Configurable 能否通过delete删除属性,能否修改属性的特性,能否把属性改为访问器属性 true
Enumerable 能否通过for-in循环返回属性 true 
get 读取属性时调用 undefined 
set 写入属性时调用   undefined
//_通常是访问器属性的标记
    var person={
        _name:'rose',
        age:18
    }
Object.defineProperty(对象,对象的属性,{
        get:function(){
            return this._name
        },
        set:function(newValue){
            this._name=newValue;
            this.age+=1
        }
    }

通过Object.defineProperty方法结合访问器属性为对象的属性设置set与get方法,最主要的一点就是可以在获取或设置该属性值的时候有一些其他的操作 比如改变_name属性名的同时也想有逻辑的改变age这时通过简单的对象.属性=xxx,只能改变本身的属性值而不能进行其他的操作,而利用这一方式可以进行其他的逻辑操作

只指定get属性是不能写的,尝试去写非严格模式下忽略,严格模式下报错 只指定set属性是不能读的,尝试去读非严格模式下undefined,严格模式下报错

setter和getter的应用

在vue中使用definedProperty来实现数据的响应式

//通过Object.defineProperties同时定义多个属性
Object.defineProperties(对象,{
    _year:{
        writable:true,
        value:2019
    },
   edition:{
        writable:true,
        value:2
    },
    year:{
        get:function(){
            return this._year
        }
    }
}

读取属性的特性

var descriptor=Object.getOwnPropertypeDescriptor(对象,属性名)

descriptor.特性