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 相关文章推荐
Raphael一个用于在网页中绘制矢量图形的Javascript库
Jan 08 Javascript
jquery怎样实现ajax联动框(一)
Mar 08 Javascript
纯JavaScript实现HTML5 Canvas六种特效滤镜示例
Jun 28 Javascript
javascript完美拖拽的实现方法
Sep 29 Javascript
SeaJS入门教程系列之SeaJS介绍(一)
Mar 03 Javascript
关于事件mouseover ,mouseout ,mouseenter,mouseleave的区别
Oct 12 Javascript
JS响应鼠标点击实现两个滑块区间拖动效果
Oct 26 Javascript
jQuery实现页面下拉100像素出现悬浮窗口的方法
Sep 05 Javascript
vuex操作state对象的实例代码
Apr 25 Javascript
Angular Material Icon使用详解
Nov 07 Javascript
6行代码实现微信小程序页面返回顶部效果
Dec 28 Javascript
如何通过简单的代码描述Angular父组件、子组件传值
Apr 07 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提取字符串中网站url地址的方法
2014/12/03 PHP
PHP跨平台获取服务器IP地址自定义函数分享
2014/12/29 PHP
php析构函数的简单使用说明
2015/08/24 PHP
PHP实现对数组分页处理实例详解
2017/02/07 PHP
默认让页面的第一个控件选中的javascript代码
2009/12/26 Javascript
JavaScript定义类或函数的几种方式小结
2011/01/09 Javascript
jquery实现预览提交的表单代码分享
2014/05/21 Javascript
seajs加载jquery时提示$ is not a function该怎么解决
2015/10/23 Javascript
基于javascript实现漂亮的页面过渡动画效果附源码下载
2015/10/26 Javascript
Bootstrap 组件之按钮(二)
2016/05/11 Javascript
JS解决iframe之间通信和自适应高度的问题
2016/08/24 Javascript
D3.js实现直方图的方法详解
2016/09/25 Javascript
jQuery的ajax中使用FormData实现页面无刷新上传功能
2017/01/16 Javascript
JavaScript使用享元模式实现文件上传优化操作示例
2018/08/07 Javascript
解决iview多表头动态更改列元素发生的错误的方法
2018/11/02 Javascript
Vue实现简单分页器
2018/12/29 Javascript
微信小程序实现简单表格
2019/02/14 Javascript
jQuery实现动态添加和删除input框代码实例
2019/03/29 jQuery
vue-cli3添加模式配置多环境变量的方法
2019/06/05 Javascript
[02:21]DOTA2英雄基础教程 蝙蝠骑士
2013/12/16 DOTA
Python中的列表生成式与生成器学习教程
2016/03/13 Python
Python实现获取前100组勾股数的方法示例
2018/05/04 Python
Pandas读取并修改excel的示例代码
2019/02/17 Python
python批量处理多DNS多域名的nslookup解析实现
2020/06/28 Python
python3.8.3安装教程及环境配置的详细教程(64-bit)
2020/11/28 Python
英国标志性奢侈品牌:Burberry
2016/07/28 全球购物
英国排名第一的最新设计师品牌手表独立零售商:TIC Watches
2016/09/24 全球购物
科颜氏法国官网:Kiehl’s法国
2019/08/20 全球购物
《果园机器人》教学反思
2014/04/13 职场文书
C++程序员求职信范文
2014/04/14 职场文书
我爱读书演讲稿
2014/05/07 职场文书
大学生活动总结模板
2014/07/02 职场文书
2016年社区党支部公开承诺书
2016/03/25 职场文书
导游词之西安骊山
2019/12/03 职场文书
mysql下的max_allowed_packet参数设置详解
2022/02/12 MySQL
Java 超详细讲解hashCode方法
2022/04/07 Java/Android