操作属性描述对象

课后整理 2020-12-10

属性描述对象是一个内部对象,无法直接读写,可以通过下面几个函数进行操作。

【示例1】在下面示例中,定义obj的x属性允许配置特性,然后使用Object.getOwnPropertyDescriptor()函数获取对象obj的x属性的属性描述对象。修改属性描述对象的set函数,重设检测条件,允许非数值型数字,也可以赋值。

var obj = Object.create(Object.prototype,  {
    _x : {                                                //数据属性 
        value : 1,                                    //初始值 
        writable:true
    },
    x: {                                                   //访问器属性 
        configurable:true,                        //允许修改配置 
        get: function( ) {                         //getter
            return  this._x ;                   //返回_x属性值 
        },
        set: function(value) {                   //setter
            if(typeof value  != "number" ) throw new Error('请输入数字');
            this._x = value;                    //赋值 
        }
    }
});
var des =  Object.getOwnPropertyDescriptor(obj, "x");       //获取属性x的属性描述对象 
des.set = function( value ){                        //修改属性x的属性描述对象的set函数 
                                                               //允许非数值型的数字,也可以进行赋值 
    if(typeof value  != "number" &&  isNaN(value * 1) ) throw new Error('请输入数字');
    this._x = value;
}
obj = Object.defineProperty(  obj, "x", des);
console.log(obj.x);                                    //1
obj.x = "2";                                              //把一个非数值型数字赋值给属性x
console.log(obj.x);                                    //2

【示例2】下面示例先定义一个扩展函数,使用它可以把一个对象包含的属性,以及丰富的信息复制给另一个对象。

【实现代码】

function extend(toObj, fromObj)  {              //扩展对象 
    for (var property in fromObj) {           //遍历对象属性 
        if (!fromObj.hasOwnProperty(property))  continue;     //过滤掉继承属性 
        Object.defineProperty(                 //复制完整的属性信息 
            toObj,                                 //目标对象 
            property,                             //私有属性 
            Object.getOwnPropertyDescriptor(fromObj,  property)       //获取属性描述对象 
        );
    }
    return toObj;                                      //返回目标对象 
}

【应用代码】

var obj = {};                                             //新建对象 
obj.x = 1;                                                 //定义对象属性 
extend(obj, { get y(){ return 2  } })             //定义读取器对象 
console.log(obj.y);                                    //2