javascript的getter和setter

工作原因,刚接触nodejs。对js的getter和setter有些缺乏了解,网上也没有找到想要的资料文献,就自己敲代码试了试。概念性的东西也不是很懂,就把今晚敲的代码结论分享下。
 
注:以下代码我用了nodejs这个运行环境
 

先看以下代码:

代码①  test3.js
javascript的getter和setter
function Field(val){  

    this.value = val;  

} 

var field = new Field("test");

field.value="test2";

console.log(field.value);      //这是输出语句
javascript的getter和setter

 

执行结果会是什么呢?
javascript的getter和setter
对,就是test2 ,这个不难理解。

但如果我将上述代码改成下面这样:
 
代码②  test3.js(修改之后)
javascript的getter和setter
function Field(val){  

    this.value = val;  

} 

Field.prototype = {  

    get value(){  

        return this._value + 1;  

    },  

    set value(val){  

        this._value = val + ‘ again‘;  

    }

};

var field = new Field("test");

field.value="test2";

console.log(field.value);
javascript的getter和setter

 

这回 结果又会是怎样呢?
javascript的getter和setter
结果是 ‘test2 again1‘, 所以从以上的两端代码中可以得到以下结论(也仅仅是我的猜测):
1. js其实是有getter和setter的,只不过是隐性的,在创建一个实例的时候这两个方法已经就存在了。
2. 代码②中我在Field原型中显式声明了getter和setter,从图中也可以看出执行结果确实比赋值语句中的‘test2‘多出‘again1‘的字样来,如实证明我将默认的getter和setter方法改写了,类似C++的重载。
 

显式重写getter的妙用:
 
再看下以下的代码:
代码③  test4.js
javascript的getter和setter
var Field = {                // 1行

    get value() {            // 2行

        return 1;              // 3行

    },                           // 4行

    get value2() {         // 5行

        return 2;             // 6行

    }                            // 7行

};                               // 8行

                                  // 9行

console.log(Field.value);    // 10行

console.log(Field.value2);   // 11行            
javascript的getter和setter

 

 
执行结果如下:
javascript的getter和setter

为什么可以这么用? 上代码其实与以下代码等同:
代码④  test5.js 
javascript的getter和setter
var Field = function() {
};

Field.prototype = {
    get value() {
        return 1;
    },
    get value2() {
        return 2;
    }
};

var field = new Field();
console.log(field.value);
console.log(field.value2);
javascript的getter和setter

 

这段代码应该好理解,代码③只是相比代码④,用了json对象来创建实例。

那么下面开始我们就从代码③逐行分析,为什么可以像第10行,11行这么用。
   1. 首先getter和setter的函数名一定要与它属于的实例的成员变量同名,如代码②中,有成员变量this.value,它的getter和setter也叫value()。那么看代码③中的第二行和第五行,有两个getter分别叫value()和value2(),但没有与之对应的成员变量,这么写可以么?
   2. 别忘了js的特性,js是动态类型,想用到什么变量直接在实例尾缀 “.”一下就能用了,如下:
        
var Exp = function() {
    // 无任何成员变量 
};

var exp = new Exp();
 exp.a = 1; 


这样,exp.a就直接可以用了。以这特性,再回过头来看看代码③的10行,11行。

在这两行中,我需要用到value和value2这两个变量,并且希望这两个变量可以返回值,这时已经写好的两个getter方法派上用场了。value和value2返回值的时候会去调用各自的getter,2行和5行已经定义好了,所以将会执行这两个getter方法,而不是默认的getter(如果自己没有定义getter,执行默认getter的话,10行 11行将都会返回undefined),因此代码③的执行结果如图那样返回的是value()和value2()里的1和2。 
       ※ 其实以上也是我的猜测,不确定我的观点百分百正确。

重头戏:了解了js的getter,setter   那么来看下getter独特的用法,和代码③的用法一样。看如下代码:
 
代码⑤  test.js
javascript的getter和setter
var Numeric = {     //这儿定义了一个json对象(这个对象只是用来存静态数据的)
    get equip() {
        return {          //这里注意,这儿又返回了一个json对象
            get normalEquip() {
                return 1;
            },      // 逗号,要注意 
            get fashionEquip() {
                return 2;
            }
        };
    },// 同样逗号
    get weapon() {
        return 11;
    }
};

var Test = function() {            //这儿声明了一个Test实例
    this.equipType = 1;
    this.weaponType = 11;
};

var pro = Test.prototype;

pro.show = function() {            //注意以下的判断及用法
    if(this.equipType == Numeric.equip.normalEquip) {
        console.log(‘is normalEquip‘);
    }else if(this.equipType == Numeric.equip.fashionEquip) {
        console.log(‘is fashionEquip‘);
    }
    if(this.weaponType == Numeric.weapon) {
        console.log(‘is Weapon!‘)
    }
};

var myTest = new Test();            //创建Test实例
myTest.show();                      //执行        
javascript的getter和setter

 

执行结果:
javascript的getter和setter
    
代码⑤中的 Numerical实例封装了所有需要用到的静态数据,用法如C++的 const变量 或是 define,这种用法给项目开发带来了很多方便,而且也便于维护。算得上是用js来实现define或者enum的一种方法。

刚接触js,有很多概念上的东西还不是很懂。上述中若有错误,希望能及时提醒与纠正。

javascript的getter和setter

上一篇:学习网站随笔记录


下一篇:浏览器打开2个页面会有几个进程?