工作原因,刚接触nodejs。对js的getter和setter有些缺乏了解,网上也没有找到想要的资料文献,就自己敲代码试了试。概念性的东西也不是很懂,就把今晚敲的代码结论分享下。
注:以下代码我用了nodejs这个运行环境
先看以下代码:
代码① test3.js
重头戏:了解了js的getter,setter 那么来看下getter独特的用法,和代码③的用法一样。看如下代码:
function Field(val){ this.value = val; } var field = new Field("test"); field.value="test2"; console.log(field.value); //这是输出语句
执行结果会是什么呢?
对,就是test2
,这个不难理解。
但如果我将上述代码改成下面这样:
代码②
test3.js(修改之后)
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);
这回 结果又会是怎样呢?
结果是 ‘test2 again1‘,
所以从以上的两端代码中可以得到以下结论(也仅仅是我的猜测):
1.
js其实是有getter和setter的,只不过是隐性的,在创建一个实例的时候这两个方法已经就存在了。
2.
代码②中我在Field原型中显式声明了getter和setter,从图中也可以看出执行结果确实比赋值语句中的‘test2‘多出‘again1‘的字样来,如实证明我将默认的getter和setter方法改写了,类似C++的重载。
显式重写getter的妙用:
再看下以下的代码:
代码③ test4.js
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行
执行结果如下:
为什么可以这么用? 上代码其实与以下代码等同:
代码④ test5.js
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);
这段代码应该好理解,代码③只是相比代码④,用了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
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(); //执行
执行结果:
代码⑤中的
Numerical实例封装了所有需要用到的静态数据,用法如C++的 const变量 或是
define,这种用法给项目开发带来了很多方便,而且也便于维护。算得上是用js来实现define或者enum的一种方法。
刚接触js,有很多概念上的东西还不是很懂。上述中若有错误,希望能及时提醒与纠正。