JavaScript之Getters和Setters 平台支持等详细介绍


Posted in Javascript onDecember 07, 2012

来自John Resig早年的文章,大致翻译了一下,以作备忘。
令人高兴的是,我想我终于可以说,“现在,JavaScript的Getters和Setters使用非常广泛,它和每个JavaScript开发者的切身利益息息相关”。靠,我为了说这句话已经等了很久了。
首先,我们先来快速了解什么是Getters和Setters,以及它们为什么很有用。然后,我们来看看现在都有哪些平台支持Gettets和Setters。
Getters和Setters
Getters和Setters使你可以快速获取或设置一个对象的数据。一般来说,一个对象拥有两个方法,分别用于获取和设置某个值,比如:

{ 
getValue: function(){ 
return this._value; 
}, 
setValue: function(val){ 
this._value = val; 
} 
}

用这种方式写JavaScript的一个明显的好处是:你可以用它来隐藏那些不想让外界直接访问的属性。最终的代码看起来就像下面这样(用闭包保存新创建的Filed对象的value):
function Field(val){ 
var value = val; 
this.getValue = function(){ 
return value; 
}; 
this.setValue = function(val){ 
value = val; 
}; 
}

于是我们可以这样使用:
var field = new Field("test"); 
field.value 
// => undefined 
field.setValue("test2") 
field.getValue() 
// => "test2"

我们来模拟上例中的 “隐藏的value属性”,我们的代码就像这样:
function Field(val){ 
var value = val; 
this.__defineGetter__("value", function(){ 
return value; 
}); 
this.__defineSetter__("value", function(val){ 
value = val; 
}); 
}

但是呢,你不喜欢这样写,而倾向在对象的prototype中定义getters和setters(私有变量写在哪并不重要),我们可以用另一种语法。
function Field(val){ 
this.value = val; 
} 
Field.prototype = { 
get value(){ 
return this._value; 
}, 
set value(val){ 
this._value = val; 
} 
};

这种语法看起来很不可思议,但是使用过一段时间之后,接受它也很容易。
接下来是另一个例子,它允许外界获取一个username数组,但是却不能获取原始的,隐藏的user对象。
function Site(users){ 
this.__defineGetter__("users", function(){ 
// JS 1.6 Array map() 
return users.map(function(user){ 
return user.name; 
}); 
}; 
}

作为福利,我写了一个方法,它可以帮你实现对象的继承,并且还考虑到了getters和setters
// Helper method for extending one object with another 
function extend(a,b) { 
for ( var i in b ) { 
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i); 
if ( g || s ) { 
if ( g ) 
a.__defineGetter__(i, g); 
if ( s ) 
a.__defineSetter__(i, s); 
} else 
a[i] = b[i]; 
} 
return a; 
}

在我的extend()方法中,你会发现两个新方法:__lookupGetter__和__lookupSetter__。一旦你真正开始使用getters和setters,这将很有用。
比如,当我第一次写extend()方法时,我遇到了各种errors,我彻底晕了。后来我发现问题就出在一个简单的语句上:a[i] = b[i];
如果对象a存在一个setter,名字叫做i,对象b存在一个getter,名字也叫做i,a[i]不是通过别的setter方法赋值的,而是来自b的getter方法。这两个__lookup*__方法使你可以获取原始的函数。(这段翻得有点晦涩,原文如下)

If a setter existed in object a, named i, and a getter existed in object b, named i, a[i]'s value was being set not to the other setter function, but to the computed value from b's getter function. The two __lookup*__ methods allow you to access the original functions used for the methods (thus allowing you to write an effective extend method, for example).


记住以下几点
一个对象内,每个变量只能有一个getter或setter。(因此value可以有一个getter和一个setter,但是value绝没有两个getters)
删除getter或setter的唯一方法是:delete object[name]。delete可以删除一些常见的属性,getters和setters。
如果使用__defineGetter__或__defineSetter__,它会重写之前定义的相同名称的getter或setter,甚至是属性(property)。
平台
支持的浏览器有
Firefox
Safari 3+
Opera 9.5
(原文没写Chrome,还没出呢)
我用下面的代码测试浏览器

javascript:foo={get test(){ return "foo"; }};alert(foo.test);

另外,以下两种引擎也支持Getters和Setters:
SpiderMonkey
Rhino 1.6R6 (New)
Javascript 相关文章推荐
日期 时间js控件
May 07 Javascript
jQuery的运行机制和设计理念分析
Apr 05 Javascript
JavaScript验证图片类型(扩展名)的函数分享
May 05 Javascript
在IE8上JS实现combobox支持拼音检索功能
May 23 Javascript
ES6概念 Symbol.keyFor()方法
Dec 25 Javascript
Angular.js自动化测试之protractor详解
Jul 07 Javascript
JavaScript学习笔记之惰性函数示例详解
Aug 27 Javascript
react native基于FlatList下拉刷新上拉加载实现代码示例
Sep 30 Javascript
js/jquery遍历对象和数组的方法分析【forEach,map与each方法】
Feb 27 jQuery
ES6中异步对象Promise用法详解
Jul 31 Javascript
详解小程序BackgroundAudioManager踩坑之旅
Dec 08 Javascript
vue实现放大镜效果
Sep 17 Javascript
缓动函数requestAnimationFrame 更好的实现浏览器经动画
Dec 07 #Javascript
javascrpt绑定事件之匿名函数无法解除绑定问题
Dec 06 #Javascript
php图像生成函数之间的区别分析
Dec 06 #Javascript
javascript SpiderMonkey中的函数序列化如何进行
Dec 05 #Javascript
javascript中有趣的反柯里化深入分析
Dec 05 #Javascript
js multiple全选与取消全选实现代码
Dec 04 #Javascript
在js(jquery)中获得文本框焦点和失去焦点的方法
Dec 04 #Javascript
You might like
PHP实现扎金花游戏之大小比赛的方法
2015/03/10 PHP
Yii中CArrayDataProvider和CActiveDataProvider区别实例分析
2016/03/02 PHP
phpmailer简单发送邮件的方法(附phpmailer源码下载)
2016/06/13 PHP
php-fpm开启状态统计的方法详解
2017/06/23 PHP
Jquery从头学起第四讲 jquery入门教程
2010/08/01 Javascript
原生js的弹出层且其内的窗口居中
2014/05/14 Javascript
node.js中的fs.exists方法使用说明
2014/12/17 Javascript
JavaScript搜索字符串并将搜索结果返回到字符串的方法
2015/04/06 Javascript
实现音乐播放器的代码(html5+css3+jquery)
2015/08/04 Javascript
javascript控制图片播放的实现代码
2020/07/29 Javascript
PhantomJS快速入门教程(服务器端的 JavaScript API 的 WebKit)
2015/08/06 Javascript
jQuery 1.9.1源码分析系列(十四)之常用jQuery工具
2015/12/02 Javascript
JS中关于事件处理函数名后面是否带括号的问题
2016/11/16 Javascript
手把手教你把nodejs部署到linux上跑出hello world
2017/06/19 NodeJs
在vue项目中,使用axios跨域处理
2018/03/07 Javascript
详解Vue项目在其他电脑npm run dev运行报错的解决方法
2018/10/29 Javascript
[01:06:07]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS CIS
2014/05/22 DOTA
Python自动重试HTTP连接装饰器
2015/04/28 Python
Python编程之多态用法实例详解
2015/05/19 Python
深入解析Python中的lambda表达式的用法
2015/08/28 Python
python批量设置多个Excel文件页眉页脚的脚本
2018/03/14 Python
Python中*args和**kwargs的区别详解
2019/09/17 Python
python代码如何注释
2020/06/01 Python
Python .py生成.pyd文件并打包.exe 的注意事项说明
2021/03/04 Python
Ticketmaster德国票务网站:购买音乐会和体育等门票
2016/11/14 全球购物
美国球迷装备的第一来源:FOCO
2020/07/03 全球购物
口腔医学技术应届生求职信
2013/11/09 职场文书
《花木兰》教学反思
2014/04/09 职场文书
我的老师教学反思
2014/05/01 职场文书
2014年党的群众路线教育实践活动整改措施(个人版)
2014/09/25 职场文书
党的群众路线教育实践活动学习笔记范文
2014/11/06 职场文书
2015年营业员工作总结
2015/04/23 职场文书
婚姻出轨保证书
2015/05/08 职场文书
初中政治教学工作总结
2015/08/13 职场文书
pytorch model.cuda()花费时间很长的解决
2021/06/01 Python
springboot应用服务启动事件的监听实现
2022/04/06 Java/Android