JavaScript之理解对象(面向对象的程序设计)

理解对象

任何事物都可以看作对象,对象就是五级无序名/值对的集合。对象有属性和方法。

对象就是 无序属性 的集合,属性可包括基本值、对象和函数,简单地说就是一组无特定顺序的值,由名/值对组成,值可以是数据或函数。属性名是字符串,我们也将对象看成是从字符串到值的映射,当然,对象除了本身的属性外,还可以从一个叫原型的对象继承属性。

在JavaScript中,除了字符串、数字、true、false、null和undefined外,其它的值均是对象。

对象可以由关键字new后跟构造函数Object()创建:

var obj = new Object();

obj.name = "Tom";
obj.age = 20;
obj.job = "javaScript";

obj.sayName = function () {
    alert(this.name);
};

对象也可以由字面量法创建:(常用的方法)

var obj = {
    name : "Tom",
    age : 20,
    job : "javaScript",

    sayName : function() {
        alert(this.name);
    }
};


属性类型

在定义只有在内部才用的特性(attribute)时,描述了属性(property)的特性,特性是内部值,将其放于两对方括号中,即[writable]。


JavaScript中有两种属性:数据属性访问器属性


数据属性

数据属性包含一个数据值的位置,这个位置可以读取和写入值。数据属性有value特性,无get、set特性。

数据属性的特性

1、[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,能否把属性修改成访问器属性。默认为true。

2、[[Enumerable]]:表示能否通过for-in遍历并返回属性。默认为true。

3、[[Writable]]:表示能否修改属性。默认为true。

4、[[Value]]:包含这个属性的数据值。读取属性值时,从这个位置读取,写入属性值,把值保存在这个位置。


var person = {
    name : "Tom"
};


这里为对象person创建了一个名为name的属性,给定值是"Tom",也就是说[[Value]]被设置成"Tom",要修改属性的默认特性,需用Object.defineProperty()方法。这个方法接收三个参数:属性所在的对象要修改或新创建的属性名一个描述符对象描述符对象必须是:configurable、enumerable、writable、value。设置其中一个或多个,可以修改对应的特性。属性名需用引号括起来

var person = {};

Object.defineProperty(person, "name", {
    writable : false,
    value : "Tom"
});

console.log(person.name); //Tom

person.name = "Bob";

console.log(person.name); //Tom


为对象person设置了一个属性name,其值为只读的。这个属性的值是不可修改的。因为设置了不能修改(writable : false)属性值name,所以最后person.name的值还是Tom。


同样也可以这样做:

var person = {};

Object.defineProperty(person, "name", {
    configurable : false; //不可通过delete删除属性并重新定义属性
    value : "Tom"
});

console.log(person.name); //Tom

delete person.name; //删除属性操作

console.log(person.name); //Tom

为对象person创建了一个属性name,并规定其不能通过delete删除,所以最后person.name还在。


:当规定对象的属性不能通过delete删除后,如果再次规定其属性能删除,则会抛出错误。

var person = {};

Object.defineProperty(person, name, {
    configurable : false; //先规定不能 通过delete删除属性并重新定义属性
    value : "Tom"
});


//抛出错误
Object.defineProperty(person, "name", {
    configurable : true; // 再次规定可以删除属性,这时会报错
    value : "Tom"
});

如果先规定对象的属性能删除,再次规定不能删除就不会出错。


以上可以总结为:

var person = {name : "jon", age : 21}; //初始化对象

Object.defineProperty(person, "name", {
    writable: false, //当设置数据为不能修改时
    configurable: true,//设置能通过delete删除属性特性
    value : "Tom" //将name的值设置为Tom
});

console.log(person.name);//通过修改特性,name的值已经被修改为Tom
//修改name的值
person.name = "Bob";
//输出还是为Tom,因为不能修改name的值
console.log(person.name);
//删除name属性的操作
delete person.name;
//undefined,已经删除name属性
console.log(person.name);


当使用Object.defineProperty()方法创建新的属性时如果先不指定属性特性,在默认情况下,configurable、enumerabel、writable均为false

Object.defineProperty()不仅可以修改属性的特性,还可以用于定义新的属性


var person = {name : "jon", age : 21};

Object.defineProperty(person, "name", {
    writable: false,
    configurable: false,
    value : "Tom"
});

Object.defineProperty(person, "name", {
    writable: true,
    configurable: true,
    value : "Tom"
});


以上代码会出错。


:多次修改除writrable以外的特性,如果第一次设置为false,那么之后如果再次设置为true,则会报错。也就是说,第一次设置为false后,再交修改为true,是不允许的,会出错的。



访问器属性

访问器属性不包含数据值,即value为undefined 。包含get()和set()方法。当读取访问属性时,会调用getter函数,当写入访问属性时,会调用setter函数。访问器属性也有四个特性:

1、[[configurable]]:能否通过delete删除属性并重新定义属性,能否修改属性,能否将属性变成数据属性。

2.[[enumerable]]:能否通过for-in遍历并返回属性。

3、[[get]]:读取属性时调用该函数。默认为undefined

4、[[set]]:写入属性时调用该函数。默认为undefined


访问器属性不能直接定义,必须通过Object.defineProerty()来定义。

var value = {
    _year : 2017,
    edition : 1
};

Object.defineProperty(value, "year",{
    get : function() { //读取并返回year属性的值
        return value.year;
    },

    set : function (newValue) {
        if (newValue > this.year) {
            this.year = newValue;  //将新值赋值于year
            this.edition += newValue - 2017;
        }
    }
});


value.year = 2018;

console.log(this.edition); //2

使用访问器属性常见方式,即改变一个属性year的值,另一个属性值_year也相应变改变。

setter和getter不一定要同时定义,当只定义getter时,只能读取属性,此时设置setter会抛出错误。同理,当只定义seter时,只能写入属性,此时再设置getter会抛出错误。



定义多个属性

可以通过Object.defineProperties()来创建多个属性。该方法接收两个 对象参数,第一个对象是 要添加和修改属性的对象,第二个对象的属性 与 第一个对象中要添加和修改的属性 一一对应。

var value = {}; //定义一个对象

Object.defineProperties(value, {

    //为对象value添加两个属性year、edition
    _year : {
        writable : true,
        value : 2017
    },
    edition : {
        writable : true,
        value : 1
    },

    //创建访问器属性
    year : {
        get : function () {
        return this.year;
    },

        set : function (newValue){
            if (newValue > this._year) {
                this.year = newValue;
                this.edition +=newValue - 2017; 
            }
        }
    }
});

value._year = 2018;

console.log(value.edition); 2

以上对象与前两个例子中的对象一样,只能此例子的两种属性是同时创建的。



读取属性的特性

使用Object.getOwnPropertyDescript()可以读取给定属性的描述符。该方法有两个参数:属性所在 对象和要读取其描述符的 属性名称。

如果是数据属性,这个对象的属性有:configurabel、enumerable、writable、value。
如果是访问器属性,这个对象的属性有:configurable、enumerable、writable、value。

var value = {};

Object.defineProperties(value, {

    //创建数据属性
    _year : {
        value : 2017
    },
    
    edition : {
        value : 1
    }
 
    //创建访问器属性
    year : {
        get : function() {
          return this.year;  
        },

        set : function(newValue) {
            if (newValue > 2017) {
                this.year = newValue;
                this.edition += newValue - 2017;
            }
        }
    }
});


//读取数据属性的特性
var descriptor = Object.getOwnPropertyDescriptor(value, "_year");
console.log(descriptor.value); //2017
console.log(descriptor.configurable); //false 默认为false 因为这个属性是通过defineProperties()新创建的。
console.log(descriptor.get); //undefined,数据属性没有get函数

//读取访问器属性的特性
var desciptor = Object.getOwnPropertyDescriptor(value, "year");
console.log(descriptor.value); //undefiend 访问器属性没有数据值
console.log(descriptor.configurable); //false 默认为false 因为这个属性是通过defineProperties()新创建的。

console.log(descriptor.get); //function

对于数据属性没有getter函数的指针。对于访问器属性没有数据值即value为undefined。configurable特性默认情况均是false


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值