javascrpt中属性描述符的理解与使用

发布日期 目录 JavaScript

javascrpt中属性描述符的理解与使用

属性描述符是ES5出现的概念。顾名思义:它用于描述对象里面的属性应该是什么样,例如是否只读,能否可枚举,能否可配置等。怎样?好理解吧。

既然是对象里面的属性相关,我们首先需要创建一个对象,才能了解对象里面的属性描述符。

创建对象

细说之前,先来看下对象的三种定义方式:
1. var obj = {};
2. var obj = new Object();
3. var obj = Object.create(proto,[description]);

这里第一种与第二种的方式其实没什么区别,只是第一种采用字面量对象的方式,而他们创建的对象都有一个默认的proto属性,这个属性指向了 Object.prototype。
而第三种,第三种有了两个参数,相当于我们在创建对象的时候可以创建我们配置的新对象,比如没有proto属性的新对象或者初始化一些不可修改的属性等等,我们主要看第三种定义对象的方法。

Object.create();

创建一个新对象 具体使用看这个 MDN:Object.create(),下面只是简单罗列下:

接收两个参数
Object.create(proto,[propertiesObject]);

参数 描述
proto 新创建对象的原型对象(即新对象的proto);可传null,定义一个没有原型对象的对象。必传参数,对象格式。
propertiesObject 要初始化的属性的描述符。可选参数,对象格式

问题:
怎样使用Object.create()方法创建一个与{}拥有一样属性的对象?

Object.create(Object.prototype) 与 {} 与new Object() 就是一样的效果,这样都只有一个属性即:proto 指向 Object.prototype。

下面着重看下第二个参数:
第二个参数是一个对象,这个对象的属性也就是新对象的属性,不过属性对应的值却不是新对象属性对应的值。是不是有点绕,因为这个属性的值(值为对象)对应这个属性的描述符(终于出现本文的概念了)。

属性描述符分两种:数据描述符与存取描述符。

先看例子:

// 第一个参数传null,创建一个干净的对象
var obj = Object.create(null, {
    // 数据描述符  name为新对象了里面自定义的属性
    name: {
        value:'seebin', // 新对象里面属性的值,即{name:"seebin"}
        writable: false,    // 该属性是否可修改 默认false
        configurable: false,// 配置属性描述符是否能够改变,以及name属性是否可以删除,默认false
        enumerable: false   // 该属性是否为枚举属性 默认为false
    },
    // 存取描述符  age为新对象了里面自定义的属性
    age: {
        get:function() { }, // 修改属性
        set:function() { }, // 读取属性
        configurable: false,// 配置属性描述符是否能够改变,以及name属性是否可以删除,默认false
        enumerable: false   // 该属性是否为枚举属性 默认为false
    }
})

注意:如果第二个参数穿空对象,相当于没有传第二个参数作为 undefined。如果第二个参数对象采用数据描述符,只写一个value,则默认writable: false,configurable: false,enumerable: false,为不可写、不可删除、不可枚举。

修改对象

上面说完了新建对象,下面说下修改对象,即修改对象的属性:新增属性、修改属性、删除属性。

一般也有几种方法修改对象:

var obj = {};
obj[name] = 'seebin';   // 新建一个属性
obj.age = 23;           // 第二种方法新建一个属性
obj.age = 45;           // 已有属性,即为修改属性
delete obj.name;        // 删除属性

上面仅仅是操作属性的值,如果我想修改这个属性为不可以修改,该如何弄?

就需要用到下面的内置方法了。

Object.defineProperty();

在对象上添加/修改一个属性,并返回这个对象的引用。

参数
Object.defineProperty(obj,prop,descriptor);

参数 描述
obj 要操作的对象
prop 要添加或修改的属性名称
descriptor 该属性的描述符

上面出现了属性描述符的概念,老样子如果想仔细了解用法,看这MDN:Object.defineProperty()

下面简单看下这个方法:

var obj = {};
// 没有name属性即可新增属性
Object.defineProperty(obj, 'name', {
    //  出现value即为数据描述符
    value:'seebin'  // 只写value,还是默认writable: false,configurable: false,enumerable: false,为不可写、不可删除、不可枚举。
})

// 上面定义了name属性不可修改,这时修改一个不可修改的属性会报错
Object.defineProperty(obj, 'name', {
    value:'小明'
})

// 再通过普通方法新增一个age属性
obj.age = 12;
// 下面将值改为123
Object.defineProperty(obj, 'age', {
    value:'123',
    writable: false // 将age属性设为不可修改  也可不写,默认行为
})

查看属性描述符

内置方法里面提供了一个方法来查看属性的属性描述符。

Object.getOwnPropertyDescriptor()

返回指定对象上一个自有属性对应的属性描述符。老样子,更多用法:MDN:Object.getOwnPropertyDescriptor()

参数:
Object.getOwnPropertyDescriptor(obj, prop)

参数 描述
obj 要操作的对象(对象类型)
prop 对象内属性名称(String类型)
var o, d;

o = { bar: 42 };
d = Object.getOwnPropertyDescriptor(o, "bar");
// d为 {
//   configurable: true,
//   enumerable: true,
//   value: 42,
//   writable: true
// }

好了,上面已经操作了设置属性描述符、修改属性描述符、查看属性描述符的功能,关于存取描述符介绍了有点少,有时间在搞吧。

发表评论

邮箱地址不会被公开。