技术专栏
合作公告  /   公司新闻  /   知识讲堂  /   技术专栏

JavaScript面向对象(1)——数据属性和访问器属性

发布时间:2016-12-11 21:59:54  发布者:赵小东  浏览次数:

创建自定义对象对简单的办法就是创建一个Object实例,如下所示。

var person = new Object();
person.name = 'Jack';
person.age = 20;
person.sayName = function(){
         alert(this.name);
}
 
person.sayName();                     //输出Jack

上面的例子用对象字面量语法可以写成:

var person = {
         name: 'Jack',
         age: 20,
         sayName: function(){
                   alert(this.name);
         }
};
 
person.sayName();  //输出Jack

一、属性类型

ECMA-262第5版在定义只有内部才用的特性(attribute)时,描述了属性(property)的各种特征。这些特性是为了实现JavaScript引擎用的,因为不能直接访问。为了表示是内部值,他们被放在两对方括号里面,如[[Enumerable]]。

ECMAScript中有两种属性:数据属性和访问器属性。

1.  数据属性

数据属性包含一个数据值的位置,可读取和写入值。数据属性有4个特性。

特性

意义

默认值

[[Configurable]]

能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。

true

[[Enumerable]]

能否通过for-in循环返回属性

true

[[Writable]]

能否修改属性值

true

[[Value]]

这个属性的属性值

undefined

Object.defineProperty(‘属性所在对象’,’属性名称’,’描述符对象’)方法来修改属性默认的特性。描述符对象属性为:configurable, enumerable, writable, value。例如:

var person = {
         age: 20,
         sayName: function(){
                   alert(this.name);
         }
};
 
Object.defineProperty(person,"name",{
         configurable: false,
         writable: false,
         enumerable: false,
         value: 'Jack'
});
 
for( var i in person){
         console.log(person[i]);
};
 
person.sayName();

writable设置为false,则无法再修改该属性的value值(否则严格模式报错)。

configurable设置为false, 则无法删除该属性(否则严格模式报错),无法设置除writeable以外的特性(否则报错)。

在使用Object.defineProperty()后,configurable, writable, enumerable将默认为false.

不支持IE8-

2. 访问器属性

访问器属性值不包含数据值,无writable和value。

特性

意义

默认值

[[Configurable]]

能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。

true

[[Enumerable]]

能否通过for-in循环返回属性

true

[[Get]]

读取属性时调用的函数

undefined

[[Set]]

写入属性时调用的函数

undefined

访问器属性和数据属性一样通过Object.defineProperty()来定义,例如。

var book = {
         name: 'book',
         _year: 2015,
         edition: 1
}
 
Object.defineProperty(book, "year", {
         get: function(){
                   return this._year ;
         },
         set: function(newValue){
                   if(newValue > 2015){
                            this._year = newValue;
                            this.edition += newValue - 2015;
                   }
         }
});
 
book.year = 2016;
alert(book.year);
console.log(book.edition + ' ' + book.year);

_year前面的下划线是一种常用的记号,用于表示只能通过对象方法访问的属性,当我们为person.name赋值时调用了getter和setter。

只设置getter意味属性不能写(严格模式报错)。

只设置setter意味属性不能读(严格模式报错)。

二、定义多个属性

定义多个属性使用Object.defineProperties(‘属性所在对象’,’属性对象’),例如:

var book = {};
 
Object.defineProperties(book,{
         name: {
                   configurable: false,
                   writable: false,
                   value: 'book'
         },
 
         _year: {
                   configurable: true,
                   writable: true,
                   value: 2015
         },
 
         edition: {
                   configurable: true,
                   writable: true,
                   value: 1
         },
 
         year: {
                   get: function(){
                            return this._year;
                   },
                   set: function(newValue){
                            if (newValue > 2015){
                                     this._year = newValue;
                                     this.edition += newValue - 2015;
                            }
 
                   }
         }
});
 
book.year = 2017;
console.log(book.edition);

不支持IE8-;

在使用Object.defineProperties()后,configurable, writable, enumerable将默认为false。

三、读取属性的特性

用Object.getOwnPropertyDescriptor(‘属性所在的对象’,’属性的名称’)方法取得属性的描述符对象,例如:

var book = {};
Object.defineProperties(book,{
         name: {
                   value: "book"
         },
 
         _year: {
                   value: 2015
         },
 
         edition: {
                   value: 1
         },
 
         year: {
                   get: function(){
                            return this._year;
                   },
                   set: function(newValue){
                            if (newValue > 2015){
                                     this._year = newValue;
                                     console.log(newValue);
                                     console.log(this._year);
                                     this.edition += newValue - 2015;
                            };
 
                   }
         }
});
 
var desciptor = Object.getOwnPropertyDescriptor(book,"year");
console.log(desciptor.get + " " + desciptor.configurable + " " + desciptor.set + " " + desciptor.enumerable);

不支持IE8-;

上一个:2016 年 7 个顶级 JavaScript 框架