首页 > 代码库 > JS中的get & set

JS中的get & set

   之前在看《Javascript 高级程序设计》一书中遇到过getter和setter,但因当时难于理解,且觉得用处较小,没有细看,今日突然遇到了一种使用get&set读写对象属性的方式。

//字面量创建对象var p={    //对象的成员:属性&方法    name:"cj",    work:function(){        console.log("working....");    },    _age:18,    //一般常用下划线开头,表示该属性只能有对象的方法进行访问。    //get读取p._age    get age(){        return this._age;    },    //set设置p._age    set age(val){        if(val<0||val>150){            throw new Error("invalid value");        }else{            this._age=val;        }    }};console.log(p.age);   //18console.log(p._age);  //18p.age=30;console.log(p.age);  //18console.log(p._age);  //18

 

 

然后在网上搜到了一组类似的用法:

    //创建一个类      var Person = function() {        //属性:姓名,注意要属性名与get和set的名称不能重复否则会报错          this._username = unknown;        this._age = 0;    }    //在原型中给set和get方法      //在原型中get和set方法的名称是一样的,方便调用      Person.prototype = {        set username(name) {    //        console.log(‘调用username的set方法‘);            this._username = name;        },        get username() {    //        console.log(‘调用了username的get方法‘);            return this._username;        }    }    var p = new Person();    console.log(p);    console.log(p.username); //unknown    p.username;    p.username = foo;    console.log(p.username);  //foo

 

 但是没能查找到更多关于get和set的信息,只能琢磨一下getter和setter:

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

数据属性包含一个数据值的位置。在这个位置可以读取和写入值。

 1、数据属性:在使用字面量形式创建的对象中,直接定义在对象上的属性,包含四个默认的属性:

  (1)[[configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。该特性默认值为true。

  (2)[[enumerable]]:表示能否通过for-in循环返回属性。该特性默认值为true。

  (3)[[writable]]:表示能否修改属性的值。该特性默认值为true。

  (4)[[value]]:包含这个属性的数据值,读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置上,该特性默认值为undefined。

如果需要修改数据属性,需要使用ECMAScript5中的object.defineProperty()方法。

var p={    name:"nicole"};Object.defineProperty(p,"name",{   value:"abc"})console.log(p.name);   //abc

2、访问器属性:不包含数据值;他们包含一对儿getter&setter函数,有如下4个特性:

  (1)configurable:表示能否通过delete删除属性从而定义新的属性,能否修改属性的特性,或者能否把属性修改为数据属性。该特性默认值为true。

  (2)enumerable:表示能否通过for-in循环返回属性。该特性默认值为true。

  (3)get:在读取属性时调用的函数。该特性默认值为undefined;

  (4)set:在写入属性时调用的函数。该特性默认值为undefined;

 

tip:_ 下划线是一种常用的记号,用于表示只能通过对象方法访问的属性。

var book={    _year:2004,    edition:1};Object.defineProperty(book,"year",{    //跟数据属性不一样,此处的year是访问器属性,_year是数据属性。    get:function(){        return this._year;    },    set:function(newValue){        if(newValue>2004){            this._year=newValue;            this.edition+=newValue-2004;        }    }})  book.year=2005;alert(book.edition);   //2

支持这种方法的浏览器有:IE9+(IE8只是部分实现),Firefox4+,Safari5+,Opera12+,Chrome.旧版创建访问器属性,一般都是用两个非标准的方法:_defineGetter_()和_defineSetter_()

3、定义多个属性

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;            }        }    }})console.log(book._year);  //2004console.log(book.edition);  //1book.year=2005;console.log(book.edition);  //2

使用ECMAScript5的Object.getOwnPropertyDescriptor(属性所在的对象,属性名称),可以取得给定属性的描述符,返回一个对象,对象包含相应的属性。

如果是数据属性,这个对象的属性有:configurable,enumerable,writable,value;

如果是访问器属性,这个对象的属性有:configurable,enumerable,get,set;

支持这个方法的浏览器有:IE9+,Firefox4+,Safari5+,Opera12+,Chrome。

++++var descriptor=Object.getOwnPropertyDescriptor(book,"_year");console.log(descriptor);var descriptor2=Object.getOwnPropertyDescriptor(book,"year");console.log(descriptor2);

第一个_year是数据属性,第二个year是访问器属性。所以最终打印出的结果如下:

技术分享

 

所以看完这里,仍然不理解最初遇到的那种写法是为何,姑且当做是在字面量对象中创建了访问器属性,来读写数据属性吧。

 

JS中的get & set