网页设计实战之JavaScript(7) -- 对象属性的特性值

对象属性除了名字和值之外,属性还包含一些标识它们可写、可枚举、可配置的特性。在 ECMAScript 3 中无法设置这些特性,所有通过 ECMAScript 3 程序创建的属性都是可写、可枚举、可配置的,且无法对这些特性做修改。ECMAScript 5 则提供了查询和设置这些属性特性的 API,这些 API 对库开发者来说比较重要。

数据属性包含四个特性:可读性可枚举性可配置性

存取器属性不具有值特性(由getter方法存在与否决定)和可写性(由setter方法存在与否决定)。

为了实现属性特性的查询与设置操作,ECMAScript 5 定义了一个名为「属性描述符」的对象,这个对象代表了那四个特性。属性描述符对象的属性和所描述的属性特性是同名的,因此其属性有:value、writable、enumerable、configurable。存取器属性的描述符对象则用 get 和 set 来代替 value 和 writable。

通过调用 Object.getOwnPropertyDescriptor() 可以获得某个对象特定属性值的属性描述符。

1.属性的特性包括下面六个:

  • configurable:
      表示能否通过delete来删除属性从而重新定义属性,能够修改属性的特性,默认为true
  • enumberable:
      表示是否能通过for-in循环返回属性。默认为true
  • writable:
      是否可以修改属性, 默认为true
  • value:
      包含这个属性的数据值。读取属性值时,从这个属性读,写入属性时,把新值保存到这个位置。默认值为undefine.
  • getter:
      在读取属性时,调用的函数
  • setter:
      在写入属性时调用的函数

一旦调用了Object.defineProperty方法之后,那些未定义的特性值除了configurable为false之外,其他都为undefined;

2、修改单个属性的特性:

必须使用Object.defineProperty()方法。这个方法接受3个参数:

  • 属性所在的对象
  • 属性的名字
  • 一个描述符对象。

其中描述符对象的属性必须是:configurable, enumberable, writable,value.设置其中一个或者多个值,可以修改对应的特性值。

另外,一旦,我们我们把某个属性的特性设置成了不可配置的,就再也不能把它变回可配置的了。此时,调用Object.defineProperty()方法修改除了writable之外的特性都会报错。

(1)、 修改writable特性:

设置为false从而使得属性值不可修改,如下所示:

var person = {};
Object.defineProperty(person, "name", {
  writable: false,//设置属性的特性为不可修改的
  value: "Tom"  //把name属性值设为Tom
});
person.name = "Jany"; //试图把name属性值设置为Jany,但是失败了.非严格模式下会忽略此语句,严格模式则会报错的
console.log(person.name); //结果仍然为Tom

(2)、修改configurabel特性,

设置为false使得属性无法被delete(删除),如下所示:

var person = {};
Object.defineProperty(person, "name", {
  configurable: false, //把configurable设置为false
  value: "Tom"
});
console.log(person.name); //打印结果为Tom
delete person.name; //试图删除name属性
console.log(person.name); //但是name仍然存在,打印出Tom

如果我们把configurable属性值改为true,则属性可以被delete

 var person = {};
Object.defineProperty(person, "name", {
  configurable: true,
  value: "Tom"
});
console.log(person.name); //打印出Tom
delete person.name; //试图删除name属性
console.log(person.name); //删除成功,打印出udefined

另外,一旦,我们我们把某个属性的特性设置成了不可配置的,就再也不能把它变回可配置的了。此时,调用Object.defineProperty()方法修改除了writable之外的特性都会报错。

var person = {};
//把person.name属性的configurable设置为false;
Object.defineProperty(person, "name", {
  configurable: false,
  value: "Tome"
});
//然后试图重新把person.name属性的configurable设置为true;但是浏览器出现报错信息。
Object.defineProperty(person, "name", {
  configurable: true,
  value: "lyl"
});
 
console.log(person.name);

(3)、修改getter和setter特性

 //定义一个对象book
var book = {
  _year: 2004, //出版年份
  edition: 1  //版本号
};

//定义year属性的特性
Object.defineProperty(book, "year", {
  //重写get方法,即如果我们试图book.year获取year值时,实质上是获取book._year的值
  get: function() {
    return this._year;
  },
  //重写了set方法,每当对book.year进行赋值时,则相应的修改book._year和book.edition的值
  set: function(newValue) {
    if(newValue > 2004) {
      this._year = newValue;
      this.edition += newValue - 2004;
    }
  }
 
});
 
book.year = 2005;
console.log(book.edition); //2

3、同时定义(修改)多个属性的特性

用Object.defineProperties方法通过描述符一次定义多个属性。这个方法接受两个对象的参数;第一个对象是要添加和修改器属性的对象,第二个对象的属性与第一个对象中要添加或者修改的顺序一一对应。

var book = {};
Object.defineProperties(book, {
  // 定义一个新的属性_year,并且他的值为2004
  _year: {
    value: 2004
  },
  // 定义一个新的属性edition,并且他的默认值是1,而且属性值是可修改的
  edition: {
    value: 1,
    writable: true// 可修改的
  },
  // 定义一个新的属性year,并且重写了他的get和set方法
  year: {
    get: function() {
      return this._year;
    },
    set: function(newValue){
      if(newValue > 2004) {
        //alert("ok");
        this._year = newValue;
        this.edition += newValue-2004;
      }
    }
  }
});
 
book.year = 2006;
console.log(book.edition);//3

4.读取属性的特性

读取属性的特性,使用Object.getOwnPropertyDescriptor方法


var book = {};
// 为该对象定义一些属性
Object.defineProperties(book, {
  _year: {
    value: 2004
  },
  edition: {
    value: 1,
    writable: true// 可修改的
  },
  year: {
    get: function() {
      return this._year;
    },
    set: function(newValue){
      if(newValue > 2004) {
        //alert("ok");
        this._year = newValue;
        this.edition += newValue-2004;
      }
    }
  }
});
 
//获取_year属性的特性
var descriptor1 = Object.getOwnPropertyDescriptor(book, "_year");
console.log(descriptor1.configurable); //false
console.log(descriptor1.enumberable); //undefinded
console.log(descriptor1.writable); //false
console.log(descriptor1.value); //2004
console.log(descriptor1.get); //undefined
console.log(descriptor1.set); //undefined
 
console.log("\n");
 
//获取year属性的特性
var descriptor2 = Object.getOwnPropertyDescriptor(book, "year");
console.log(descriptor2.configurable); //false
console.log(descriptor2.enumberable); //undefined
console.log(descriptor2.writable); //undefined
console.log(descriptor2.value); //undefined
console.log(descriptor2.get); //function()
console.log(descriptor2.set); //function(value)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值