js面向对象的程序设计 --- 上篇(理解对象)
前言
ECMAScript中没有类的概念,因此它们的对象与基于类的语言中的对象有所不同。
ECMA-262把对象定义为:"无序的集合属性,其属性可以包含基本值,对象或者函数"。正因为这样,我们可以把ECMAScript想象成散列表:
无非就是一组名值对,其中值可以是数据或者函数,
每个对象都是基于一个引用类型创建的,这个引用类型可以是第5章讨论的原生类型,也可以是开发人员定义的类型
·理解对象
·属性类型
ECMA-262定义了只有自内部才用指定特性时,描述了属性的各种特征。ECMA-262定义这些特性是为了实现javascript引擎用的,因此在javascript
中不能直接访问它们。为了表示特性是内部值,该规范把它们放在两对儿方括号中,例如:[[Enumerable]]
1. 数据属性
数据属性包含一个数据值的位置。在这个位置可以读取和写入。数据属性有4个描述其行为的特性
·[[CONFIGURABLE]] : 能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。
直接在对象上定义的属性,它们的这个特性默认值为true
·[[Enumerable]] : 表示能否通过 for-in 循环返回出行 。 默认 true
·[[Writable]] : 表示能否修改属性的值。 默认 true
·[[Value]] : 包含这个属性的数据值。读取属性的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。默认为undefined
2. 访问器属性
访问器属性不包含数据值;它们包含一对getter 和 setter 函数 (不过,这两个函数都不是必需的)。
·[[CONFIGURABLE]] : 能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。
直接在对象上定义的属性,它们的这个特性默认值为true
·[[Enumerable]] : 表示能否通过 for-in 循环返回出行 。 默认 true
·[[Get]] : 在读取属性时调用的函数。默认值为undefined
·[[Set]] : 在写入属性时调用的函数。默认值为undefined
·心得:ECMAScript中并没有直接定义一个属性是数据属性还是访问器属性。
根据个人心得:
如果直接指定了get 特性或者 set 特性,那么就是访问器属性。如果指定了任何数据属性特性中的一个,那么就是数据属性。
如果没有把 CONFIGURABLE 设为false ,那么数据属性和访问器属性可以互相转换
<script> var person = {name : "Leo"}; // 定义访问器属性 Object.defineProperty(person,"style",{ configurable : false, get : function () { return "style:"+this.name; }, set : function (value) { this.name = value; } }); console.log(person.style); // 触发访问器属性的get方法 // 输出style:Leo person.style = 'mystyle'; // 触发访问器属性的set方法 // 输出style:mystyle console.log(person.style); // 修改为数据属性 Object.defineProperty(person,"style",{ value : '' // 访问器属性以及定义了 configurable : false ,即表示不能把属性定义为数据属性,还强行定义,自然就报错了 }); </script>
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script> // 由于对象定义多个属性的可能性非常大。ECMAScript5又定义了一个Object.defineProperties() 方法。 // 这次,我们把数据属性和访问器属性放在一个方法里面 var book = {}; Object.defineProperties(book,{ __year : { writable : true , value : 2004, }, edition : { writable : true, value : 1, }, year : { get : function () { return this.__year; }, set : function (newValue) { if(newValue > 2004){ this._year = newValue; this.edition += newValue - 2004; } } } }) // 使用ECMAScript5的Object.getOwnPropertyDescriptor() 方法,可以取得给定属性的描述符 var descriptor = Object.getOwnPropertyDescriptor(book,'__year'); console.log(descriptor); //{value: 2004, writable: true, enumerable: false, configurable: false} console.log(Object.getOwnPropertyDescriptor(window,'year')); //{get: ƒ, set: ƒ, enumerable: false, configurable: false} // 记住: 在ECMAScript中,可以针对任何对象使用Object.getOwnPropertyDescriptor() 方法,包括DOM对象和BOM对象 </script> </body> </html>