物件内的存取器是由get
及set
去设定的,而存取器的设定可以用像是特性一样的方式去使用他,他们两者不同的地方是存取器属性可以以get
和set
去控制该特性被读写的功能,get
就代表读取,set
则是写入,拥有两个属性就可以同时被读写。
首先用get
来控制一个存取器的读取功能,以下实作:
//用get在物件obj内设定一个只能读取的存取器namevar objA = { get name(){ return 'objName'; },};//读取name会得到return的'objName'objA.name; //回传'objName'//而虽然他能够像特性般拥有值,但是实际上该物件是没有这个特性的objA; //回传空物件{} //因为只有get的读取属性,没有set的写入,所以他无法设定值objA.name = 'objA'; //将obj.name的值设定为'objA'//所以在设定完后检查该物件,一样会是空的objA; //回传空物件{}
接着我们再来只用set
来控制一个存取器的写入功能,set
和get
设置的时候有个不同点,set
必须拥有一个能够传进引数的变数,因为当我们在写入值的时候,存取器会将我们设置的值放进该变数中,以下实作:
//用set在物件内设定一个只能写入的存取器name,括号内的val就是设置的值传入的位置,这里我们让存取器去写入值到this.objName中,this指的是该物件,所以也就是为objB增加一个特性,让我们设定的值指定objB.objNamevar objB = { set name(val){ this.objName = val; },};//为该存取器设置值objB.name = 'objB'; //此时存取器中跑的程式为:objB.objName='objB'//而我们试着去读取存取器为我们新增的特性objB.objName; //会回传'objB'//但是因为没有设置get所以他无法读出该存取器拥有的值objB.name; //回传undefined//当然该物件会出现存取器为我们设定的特性objB; //回传{objName: "objB"}
最后来同时使用get
和set
让该存取器同时拥有读取及写入的功能
//在物件内同时设定拥有读取和写入的存取器name,这次我们在get内读取物件中的objName的值,并将他回传var objC = { get name(){ return this.objName; }, set name(val){ this.objName = val; },};//读取该存取器会得到undefined,因为我们还没有为该特性objName指定值objC.name; //回传'undefined'//接着为该存取器设值'objC'objC.name = 'objC'; //此时存取器会将'objC'指定给objC.objName//再试着使用存取器读出this.objName,也就是objC.objName试试objC.name; //会回传'objC'//最后再来看一下该物件目前的样子objC; //会出现一个被存取器设置的特性{objName: "objC"}
基本用法大概就是这样,但是他和一般特性一样,如果未用set
设值前get
是指会回传undefined的,不过既然他的get
中可以写程式,那就可以想办法克服这一点,例如:
//在get中加入判断式,如果再读取this.objName时,该特性不为undefuned的话就回传该特性的值,但如果为undefined就回传预设的'defaultName'var objD = { get name(){if(this.objName){return this.objName}else{ return 'defaultName';} }, set name(val){ this.objName = val; },};//在不先设值的情况下去读取存取器name,因为目前this.objName还是undefined,所以会回传预设的'defaultName'objD.name; //回传'defaultName'//指定一个值给存取器nameobjD.name = 'objD';//再读一次存取器name,因为这时候this.objName已经有被指定值,所以就会回传特性本身的值'objD'objD.name; //会回传'objD'
最后要注意的事情是,存取器的名称不能和特性的名称重複,否则设置时会发生错误,例如:
//如果我们在get和set中都用和存取器本身重複的名称,那不论读取或写入都会出错var objE = { get name(){ return this.name; }, set name(val){ this.name = val; },};//读取该存取器的值objE.name; //会出错'RangeError'!!!//设置该存取器的值objE.name = 'objE'; //还是会出错'RangeError'!!
以上对于存取器的说明,如果我有观念错误或解释不清楚的地方,还麻烦各位大大指点了,谢谢大家!