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动态调整iframe高度的代码
Apr 10 Javascript
JavaScript类和继承 constructor属性
Mar 04 Javascript
jquery给图片添加鼠标经过时的边框效果
Nov 12 Javascript
使用js判断数组中是否包含某一元素(类似于php中的in_array())
Dec 12 Javascript
点击标签切换和自动切换DIV选项卡
Aug 10 Javascript
jQuery的deferred对象详解
Nov 12 Javascript
jQuery 选择器详解
Jan 19 Javascript
js实现登陆遮罩效果的方法
Jul 28 Javascript
获取IE浏览器Cookie信息的方法
Jan 23 Javascript
微信网页登录逻辑与实现方法
Apr 29 Javascript
vue自定义组件(通过Vue.use()来使用)即install的用法说明
Aug 11 Javascript
nestjs返回给前端数据格式的封装实现
Feb 22 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下获取Discuz论坛登录用户名、用户组、用户ID等信息的实现代码
2010/12/29 PHP
php数组的一些常见操作汇总
2011/07/17 PHP
thinkphp实现面包屑导航(当前位置)例子分享
2014/05/10 PHP
PHP chr()函数讲解
2019/02/11 PHP
yii 框架实现按天,月,年,自定义时间段统计数据的方法分析
2020/04/04 PHP
PJBlog插件 防刷新的在线播放器
2006/10/25 Javascript
jquery学习笔记 用jquery实现无刷新登录
2011/08/08 Javascript
JavaScript高级程序设计(第3版)学习笔记5 js语句
2012/10/11 Javascript
js 删除数组的几种方法小结
2014/02/21 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
如何在MVC应用程序中使用Jquery
2014/11/17 Javascript
javascript创建动态表单的方法
2015/07/25 Javascript
Knockout自定义绑定创建方法
2015/12/26 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
2017/01/04 Javascript
javascript  删除select中的所有option的实例
2017/09/17 Javascript
手把手教你使用vue-cli脚手架(图文解析)
2017/11/08 Javascript
Vue开发Html5微信公众号的步骤
2019/04/11 Javascript
JavaScript中AOP的实现与应用
2019/05/06 Javascript
JavaScript的变量声明与声明提前用法实例分析
2019/11/26 Javascript
Python open读写文件实现脚本
2008/09/06 Python
centos系统升级python 2.7.3
2014/07/03 Python
python django 增删改查操作 数据库Mysql
2017/07/27 Python
PyCharm安装第三方库如Requests的图文教程
2018/05/18 Python
对pyqt5之menu和action的使用详解
2019/06/20 Python
python安装virtualenv虚拟环境步骤图文详解
2019/09/18 Python
如何打包Python Web项目实现免安装一键启动的方法
2020/05/21 Python
Python基于BeautifulSoup爬取京东商品信息
2020/06/01 Python
keras 实现轻量级网络ShuffleNet教程
2020/06/19 Python
python palywright库基本使用
2021/01/21 Python
介绍一下代理模式(Proxy)
2014/10/17 面试题
体育专业求职信
2014/07/16 职场文书
2014卖家双十一活动策划书
2014/09/29 职场文书
个人工作年终总结
2015/03/09 职场文书
电影焦裕禄观后感
2015/06/09 职场文书
MySQL的存储过程和相关函数
2022/04/26 MySQL
使用Apache Camel表达REST服务的方法
2022/06/10 Servers