面向对象的程序设计 --- 上篇(理解对象)

前言
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>

猜你喜欢

转载自www.cnblogs.com/cl94/p/11257661.html