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 动态加载脚本的4种方法
May 05 Javascript
JavaScript和CSS交互的方法汇总
Dec 02 Javascript
深入分析jsonp协议原理
Sep 26 Javascript
jquery实现图片放大镜功能
Nov 23 Javascript
信息页文内画中画广告js实现代码(文中加载广告方式)
Jan 03 Javascript
AngularJS中如何使用$http对MongoLab数据表进行增删改查
Jan 23 Javascript
vue移动端实现下拉刷新
Apr 22 Javascript
支付宝小程序tabbar底部导航
Nov 06 Javascript
VueJS 组件参数名命名与组件属性转化问题
Dec 03 Javascript
小程序实现左右来回滚动字幕效果
Dec 28 Javascript
如何解决日期函数new Date()浏览器兼容性问题
Sep 11 Javascript
JSON获取属性值方法代码实例
Jun 30 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
简单介绍下 PHP5 中引入的 MYSQLI的用途
2007/03/19 PHP
php将url地址转化为完整的a标签链接代码(php为url地址添加a标签)
2014/01/17 PHP
ThinkPHP模板中数组循环实例
2014/10/30 PHP
php基于CodeIgniter实现图片上传、剪切功能
2016/05/14 PHP
thinkPHP5 tablib标签库自定义方法详解
2017/05/10 PHP
php格式文件打开的四种方法
2018/02/24 PHP
javascript应用:Iframe自适应其加载的内容高度
2007/04/10 Javascript
javascript 24小时弹出一次的代码(利用cookies)
2009/09/03 Javascript
javascript中如何处理引号编码"
2013/08/15 Javascript
jquery按回车提交数据的代码示例
2013/11/05 Javascript
jquery队列queue与原生模仿其实现方法分享
2014/03/25 Javascript
分享javascript实现的冒泡排序代码并优化
2016/06/05 Javascript
整理关于Bootstrap表单的慕课笔记
2017/03/29 Javascript
js中less常用的方法小结
2017/08/09 Javascript
Vue.use()在new Vue() 之前使用的原因浅析
2019/08/26 Javascript
解决vue axios跨域 Request Method: OPTIONS问题(预检请求)
2020/08/14 Javascript
谈谈如何手动释放Python的内存
2016/12/17 Python
在Python程序员面试中被问的最多的10道题
2017/12/05 Python
python处理csv中的空值方法
2018/06/22 Python
opencv实现简单人脸识别
2021/02/19 Python
利用python Selenium实现自动登陆京东签到领金币功能
2019/10/31 Python
python3处理word文档实例分析
2020/12/01 Python
纯CSS绘制漂亮的圆形图案效果
2014/05/07 HTML / CSS
会计系个人求职信范文分享
2013/12/20 职场文书
大学自我鉴定范文
2013/12/26 职场文书
业务副厂长岗位职责
2014/01/03 职场文书
给男朋友的道歉信
2014/01/12 职场文书
高中生操行评语
2014/04/25 职场文书
学校募捐倡议书
2014/05/14 职场文书
经理任命书模板
2014/06/06 职场文书
优秀中职教师事迹材料
2014/08/26 职场文书
房屋产权证明书
2014/10/15 职场文书
个人维稳承诺书
2015/05/04 职场文书
保险公司增员口号
2015/12/25 职场文书
python四个坐标点对图片区域最小外接矩形进行裁剪
2021/06/04 Python
Redis安装使用RedisJSON模块的方法
2022/03/23 Redis