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 相关文章推荐
javascript实现仿银行密码输入框效果的代码
Dec 13 Javascript
JavaScript操作XML 使用百度RSS作为新闻源示例
Feb 17 Javascript
JS获取select的value和text值的简单实例
Feb 26 Javascript
原生JS绑定滑轮滚动事件兼容常见浏览器
Jun 30 Javascript
12种JavaScript常用的MVC框架比较分析
Nov 16 Javascript
jquery+json实现分页效果
Mar 07 Javascript
AngularJS动态加载模块和依赖的方法分析
Nov 08 Javascript
学习使用jQuery表单验证插件和日历插件
Feb 13 Javascript
AngularJS中table表格基本操作示例
Oct 10 Javascript
angular将html代码输出为内容的实例
Sep 30 Javascript
js实现双色球效果
Aug 02 Javascript
ES5和ES6中类的区别总结
Dec 21 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与javascript对多项选择的处理
2006/10/09 PHP
php查看请求头信息获取远程图片大小的方法分享
2013/12/25 PHP
php连接微软MSSQL(sql server)完全攻略
2016/11/27 PHP
PHP 与 UTF-8 的最佳实践详细介绍
2017/01/04 PHP
用jscript实现列出安装的软件列表
2007/06/18 Javascript
JQuery 图片延迟加载并等比缩放插件
2009/11/09 Javascript
JavaScript 用cloneNode方法克隆节点的代码
2012/10/15 Javascript
JavaScript中为什么null==0为false而null大于=0为true(个人研究)
2013/09/16 Javascript
JavaScript 异常处理 详解
2015/02/06 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
JS实现浏览器状态栏文字从右向左弹出效果代码
2015/10/27 Javascript
jQuery Timelinr实现垂直水平时间轴插件(附源码下载)
2016/02/16 Javascript
jQuery针对input的class属性写了多个值情况下的选择方法
2016/06/03 Javascript
Jq通过td获取同行其它列td的方法
2016/10/05 Javascript
node.js中的事件处理机制详解
2016/11/26 Javascript
详解jquery validate实现表单验证 (正则表达式)
2017/01/18 Javascript
JavaScript实现三级联动菜单实例代码
2017/06/26 Javascript
jquery实现楼层滚动效果
2018/01/01 jQuery
如何利用@angular/cli V6.0直接开发PWA应用详解
2018/05/06 Javascript
详解Vue-cli中的静态资源管理(src/assets和static/的区别)
2018/06/19 Javascript
Vue的v-model的几种修饰符.lazy,.number和.trim的用法说明
2020/08/05 Javascript
[41:37]DOTA2北京网鱼队选拔赛——冲击职业之路
2015/04/13 DOTA
用Python删除本地目录下某一时间点之前创建的所有文件的实例
2017/12/14 Python
python学习笔记--将python源文件打包成exe文件(pyinstaller)
2018/05/26 Python
Python中捕获键盘的方式详解
2019/03/28 Python
python开头的coding设置方法
2019/08/08 Python
FFrpc python客户端lib使用解析
2019/08/24 Python
flask 实现上传图片并缩放作为头像的例子
2020/01/09 Python
基于Python pyecharts实现多种图例代码解析
2020/08/10 Python
20行Python代码实现一款永久免费PDF编辑工具的实现
2020/08/27 Python
法律进社区实施方案
2014/03/21 职场文书
临时工聘用合同协议书
2014/10/29 职场文书
2014年财政局工作总结
2014/12/09 职场文书
建党伟业观后感
2015/06/01 职场文书
本科毕业论文答辩稿
2015/06/23 职场文书
Mysql多层子查询示例代码(收藏夹案例)
2022/03/31 MySQL