javaScript对象的内部特性

对象

理解对象

对象可以定义为一组属性的无序集合。严格来说,这意味着对象就是一组没有特定顺序的
值。对象的每个属性或方法都由一个名称来标识,这个名称映射到一个值。可以把对象想象成一张散列表,其中的内容就是一组名/值对,值可以是数据或者函数。

属性的类型

对象中会有一些内部特性来描述属性的特征。这些特性是由为 JavaScript 实现引擎的规范定义的,开发者不能在 JavaScript 中直接访问这些特性。为了将某个特性标识为内部特性,规范会用两个中括号把特性的名称括起来,比如[[Enumerable]]
属性分两种:数据属性访问器属性

数据属性

数据属性包含一个保存数据值的位置。值会从这个位置读取,也会写入到这个位置。数据属性有 4个特性描述它们的行为。

[[Configurable]]:表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特性,以及是否可以把它改为访问器属性。默认情况下,所有直接定义在对象上的属性的这个特性都是 true,如前面的例子所示。
[[Enumerable]]:表示属性是否可以通过 for-in 循环返回。默认情况下,所有直接定义在对象上的属性的这个特性都是 true,如前面的例子所示。
[[Writable]]:表示属性的值是否可以被修改。默认情况下,所有直接定义在对象上的属性的这个特性都是 true,如前面的例子所示。
[[Value]]:包含属性实际的值。这就是前面提到的那个读取和写入属性值的位置。这个特性的默认值为 undefined。

要修改属性的默认特性,就必须使用 Object.defineProperty()方法。这个方法接收 3 个参数:
要给其添加属性的对象、属性的名称和一个描述符对象。最后一个参数,即描述符对象上的属性可以包
含:configurable、enumerable、writable 和 value,跟相关特性的名称一一对应。根据要修改
的特性,可以设置其中一个或多个值。比如:

let person = {}; 
Object.defineProperty(person, "name", { 
 writable: false, 
 value: "Nicholas" 
}); 
console.log(person.name); // "Nicholas" 
person.name = "Greg"; 
console.log(person.name); // "Nicholas"

这个例子创建了一个名为 name 的属性并给它赋予了一个只读的值"Nicholas"。这个属性的值就
不能再修改了,在非严格模式下尝试给这个属性重新赋值会被忽略。在严格模式下,尝试修改只读属性
的值会抛出错误。

访问器属性

访问器属性不包含数据值。相反,它们包含一个获取(getter)函数和一个设置(setter)函数,不过这两个函数不是必需的。在读取访问器属性时,会调用获取函数,这个函数的责任就是返回一个有效的值。在写入访问器属性时,会调用设置函数并传入新值,这个函数必须决定对数据做出什么修改。访问器属性有 4 个特性描述它们的行为。

[[Configurable]]:表示属性是否可以通过 delete 删除并重新定义,是否可以修改它的特性,以及是否可以把它改为数据属性。默认情况下,所有直接定义在对象上的属性的这个特性都是 true。
[[Enumerable]]:表示属性是否可以通过 for-in 循环返回。默认情况下,所有直接定义在对象上的属性的这个特性都是 true。
[[Get]]:获取函数,在读取属性时调用。默认值为 undefined。
[[Set]]:设置函数,在写入属性时调用。默认值为 undefined。

访问器属性是不能直接定义的,必须使用 Object.defineProperty()。下面是一个例子:

// 定义一个对象,包含伪私有成员 year_和公共成员 edition 
let book = { 
 year_: 2017, 
 edition: 1
}; 
Object.defineProperty(book, "year", { 
 get() { 
 	return this.year_; 
 }, 
 set(newValue) { 
	 if (newValue > 2017) { 
	 this.year_ = newValue; 
	 this.edition += newValue - 2017; 
 	} 
 } 
}); 
book.year = 2018; 
console.log(book.edition); // 2

定义多个属性

在一个对象上同时定义多个属性的可能性是非常大的。为此,ECMAScript 提供了 Object.defineProperties()方法。这个方法可以通过多个描述符一次性定义多个属性。它接收两个参数:要为之添加或修改属性的对象和另一个描述符对象,其属性与要添加或修改的属性一一对应。比如:

let book = {};
Object.defineProperties(book, {
  year_: {
    value: 2017,
  },
  edition: {
    value: 1,
  },
  year: {
    get() {
      return this.year_;
    },
    set(newValue) {
      if (newValue > 2017) {
        this.year_ = newValue;
        this.edition += newValue - 2017;
      }
    },
  },
});
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值