码迷,mamicode.com
首页 > 编程语言 > 详细

javascript面向对象系列1——理解对象

时间:2015-09-12 00:39:11      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:

【对象定义】无序属性的集合,其属性可以包含基本值、对象或者函数

//简单的对象实例
var person = new Object();
    person.name = "Nicholas";
    person.age = 29;
    person.job = "Software Engineer";
    person.sayName = function(){
        alert(this.name);
    }

 

【内部属性类型】内部属性无法直接访问,ECMAScript5把它们放在两对方括号中,分为数据属性和访问器属性

  [1]【数据属性】包含一个数据值的位置,在这个位置可以读取和写入值。数据属性有4个特性:
    a、[[Configurable]]: 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,直接在对象上定义的属性,默认值为true
    b、[[Enumerable]]: 表示能否通过for-in循环返回属性,直接在对象上定义的属性,默认值为true
    c、[[Writable]]: 表示能否修改属性的值,直接在对象上定义的属性,默认值为true
    d、[[Value]]: 包含这个属性的数据值,读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。直接在对象上定义的属性,默认值为undefined

  [2]【访问器属性】不包含数据值,包含一对getter和setter函数(不过这两个函数不是必需的)。读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理函数。访问器属性有如下4个特性:
    a、[[Configurable]]: 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。直接在对象上定义的属性,默认值为true
    b、[[Enumerable]]: 表示能否通过for-in循环返回属性,直接在对象上定义的属性,默认值为true
    c、[[Get]]: 在读取属性时调用的函数。默认值为undefined
    d、[[Set]]: 在写入属性时调用的函数。默认值为undefined

 

【修改内部属性】使用ECMAScript5的object.defineProperty()方法,该方法接收三个参数:属性所在的对象、属性的名字和一个描述符对象
  [注意1]IE8是第一个实现Object.defineProperty()方法的浏览器版本。然而,这个版本的实现存在诸多限制:只能在DOM对象上使用这个方法,而且只能创建访问器属性。由于实现不彻底,不建议在IE8中使用Object.defineProperty()方法
  [注意2]不支持Object.defineProperty()方法的浏览器中不能修改[[Configurable]]和[[Enumerable]]
  [1]【修改数据属性】

//直接在对象上定义的属性,Configurable、Enumerable、Writable为true
var person = {
    name:‘cook‘
};
Object.defineProperty(person,‘name‘,{
    value: ‘Nicholas‘
});
alert(person.name);//‘Nicholas‘
person.name = ‘Greg‘;
alert(person.name);//‘Greg‘    
//不是在对象上定义的属性,Configurable、Enumerable、Writable为false
var person = {};
Object.defineProperty(person,‘name‘,{
    value: ‘Nicholas‘
});
alert(person.name);//‘Nicholas‘
person.name = ‘Greg‘;
alert(person.name);//‘Nicholas‘
//该例子中设置writable为false,则属性值无法被修改
var person = {};
Object.defineProperty(person,‘name‘,{
    writable: false,
    value: ‘Nicholas‘
});
alert(person.name);//‘Nicholas‘
person.name = ‘Greg‘;
alert(person.name);//‘Nicholas‘    
//该例子中设置configurable为false,则属性不可配置
var person = {};
Object.defineProperty(person,‘name‘,{
    configurable: false,
    value: ‘Nicholas‘
});
alert(person.name);//‘Nichols‘
delete person.name;
alert(person.name);//‘Nicholas‘

    [注意]一旦把属性定义为不可配置的,就不能再把它变回可配置了,也就是说可以多次调用Object.defineProperty()修改同一属性,但在把configurable设置为false之后,就有限制了

var person = {};
Object.defineProperty(person,‘name‘,{
    configurable: false,
    value: ‘Nicholas‘
});
//会报错
Object.defineProperty(person,‘name‘,{
    configurable: true,
    value: ‘Nicholas‘
});

  [2]【修改访问器属性】

//简单的修改访问器属性的例子
var book = {
    _year: 2004,
    edition: 1
};
Object.defineProperty(book,‘year‘,{
    get: function(){
        return this._year;
},
    set: function(newValue){
        if(newValue > 2004){
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book.year = 2005;
alert(book.year)//2005
alert(book.edition);//2

    [注意1]只指定getter意味着属性是不能写

var book = {
    _year: 2004,
    edition: 1
};
Object.defineProperty(book,‘year‘,{
    get: function(){
        return this._year;
    },
});
book.year = 2005;
alert(book.year)//2004    

    [注意2]只指定setter意味着属性不能读

var book = {
    _year: 2004,
    edition: 1
};
Object.defineProperty(book,‘year‘,{
    set: function(newValue){
        if(newValue > 2004){
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
});
book.year = 2005;
alert(book.year);//undefined

    【补充】创建访问器属性的用两个非标准的方法:__defineGetter__()和__defineSetter__()

var book = {
    _year: 2004,
    edition: 1
};
//定义访问器的旧有方法
book.__defineGetter__(‘year‘,function(){
    return this._year;
});
book.__defineSetter__(‘year‘,function(newValue){
    if(newValue > 2004){
        this._year = newValue;
        this.edition += newValue - 2004;
    }
});
book.year = 2005;
alert(book.year);//2005
alert(book.edition);//2

 

【定义多个属性】ECMAScript5定义了一个Object.defineProperties()方法,利用这个方法可以通过描述符一次定义多个属性,这个方法接收两个对象参数:第一个对象是要添加和修改其属性的对象,第二个对象的属性与第一个对象要添加或修改的一一对应

var book = {};
Object.defineProperties(book,{
    _year: {
        value: 2004
    },
    edition: {
        value: 1
    },
    year: {
        get: function(){
            return this._year;
        },
        set: function(newValue){
            if(newValue > 2004){
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    }
});

 

【读取属性特性】使用ECMAScript5的Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符。该方法接收两个参数:属性所在对象和要读取其描述符的属性名称,返回值是一个对象。
  [注意]可以针对任何对象——包括DOM和BOM对象,使用Object.getOwnPropertyDescriptor()方法

var book = {};
Object.defineProperties(book,{
    _year: {
        value: 2004
    },
    edition: {
        value: 1
    },
    year: {
        get: function(){
            return this._year;
        },
        set: function(newValue){
            if(newValue > 2004){
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    } 
});
var descriptor = Object.getOwnPropertyDescriptor(book,‘_year‘);
alert(descriptor.value);//2004
alert(descriptor.configurable);//false
alert(typeof descriptor.get);//‘undefined‘

var descriptor = Object.getOwnPropertyDescriptor(book,‘year‘);
alert(descriptor.value);//‘undefined‘
alert(descriptor.configurable);//false
alert(typeof descriptor.get);//‘function‘

 

javascript面向对象系列1——理解对象

标签:

原文地址:http://www.cnblogs.com/xiaohuochai/p/4802347.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!