第六章 面向对象的程序设计 数据属性+访问器属性

6.1 理解对象

1:属性类型(数据属性+访问器属性)

①数据属性:

[[Configurable]]是否可以删除属性

[[Enumerable]]是否可以通过for-in循环返回属性

[[Writable]]是否可以修改属性

[[Value]]属性的数据值

        var person = {
        };
        Object.defineProperty(person,"name",{
            writable:false,    
            value: "wang"
        });
        alert(person.name);        
        //wang

②访问器属性

[[Configurable]]是否可以删除属性

[[Enumerable]]是否可以通过for-in循环返回属性

[[Get]]读取属性时调用的函数

[[Set]]写入属性时调用的函数

        var person = {
            name: "2005"
        };
        Object.defineProperty(person,"name",{
            get: function(){
                return this.name;
            },
            set: function(newValue){
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        });
        alert(person.name);

上面这种写法会出现Uncaught RangeError: Maximum call stack size exceeded这种报错,之所以会报错,是因为不断的get会继续触发get,进入死循环,导致内存溢出!

        var person = {
            _name: "2005"
        };
        Object.defineProperty(person,"name",{
            get: function(){
                return this._name;
            },
            set: function(newValue){
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        });
        alert(person.name);

这种写法将有的name写成_name可以正确访问到

【注】访问器属性和数据属性的后两个属性如果同时写在一个defineProperty函数中的话,会报错。需要分开写。

2:定义多个属性

Object.defineProperties(x,y)  x接收对象,y的属性与第一个对象中要添加或修改的属性一一对应

var book = {};

Object.defineProperties(books,{
      _year : {
            value:2004 
} ,
      edition:{
            value:1
}
       year:{
            get:function(){
                  return this._year;
},
            set:function(newValue){
                  if(newValue>2004){
                     this._year = newValue;
                     this.edition += newValue -2004;
}
}          
}
});

3:读取多个属性

var book = {};

Object.defineProperties(books,{
      _year : {
            value:2004 
} ,
      edition:{
            value:1
}
       year:{
            get:function(){
                  return this._year;
},
            set:function(newValue){
                  if(newValue>2004){
                     this._year = newValue;
                     this.edition += newValue -2004;
}
}          
}
});

var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
//数据属性对象,可以访问数据属性的四个属性
var descriptor = Object.getOwnPropertyDescriptor(book,"year");
//访问器属性对象,可以访问访问器属性的四个属性

 【注】_year前面的下划线是一种常用记号,用于表示只能通过对象方法访问的属性

原文地址:https://www.cnblogs.com/cndotabestdota/p/5711546.html