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 学习笔记(十五)
Jan 28 Javascript
javascript开发技术大全 第4章 直接量与字符集
Jul 03 Javascript
一个可以增加和删除行的table并可编辑表格中内容
Jun 16 Javascript
基于jQuery实现的图片切换焦点图整理
Dec 07 Javascript
封装好的javascript前端分页插件pagination
Jan 04 Javascript
jquery删除table当前行的实例代码
Oct 07 Javascript
jquery利用json实现页面之间传值的实例解析
Dec 12 Javascript
微信小程序开发图片拖拽实例详解
May 05 Javascript
浅析node Async异步处理模块用例分析及常用方法介绍
Nov 17 Javascript
Vue2.x中利用@font-size引入字体图标报错的解决方法
Sep 28 Javascript
深入了解JavaScript代码覆盖
Jun 13 Javascript
解决vue单页面修改样式无法覆盖问题
Aug 05 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
海贼王:最美的悬赏令!
2020/03/02 日漫
php中sprintf与printf函数用法区别解析
2014/02/17 PHP
ThinkPHP中的create方法与自动令牌验证实例教程
2014/08/22 PHP
PHP实现在线阅读PDF文件的方法
2015/06/17 PHP
Yii视图操作之自定义分页实现方法
2016/07/14 PHP
Yii2语言国际化的配置教程
2018/08/19 PHP
CI框架附属类用法分析
2018/12/26 PHP
IE 上下滚动展示模仿Marquee机制
2009/12/20 Javascript
Jquery下:nth-child(an+b)的使用注意
2011/05/28 Javascript
使用JS+plupload直接批量上传图片到又拍云
2014/12/01 Javascript
JS建造者模式基本用法实例分析
2015/06/30 Javascript
详解js中class的多种函数封装方法
2016/01/03 Javascript
jQuery获取checkbox选中的值
2016/01/28 Javascript
JavaScript获取IP获取的是IPV6 如何校验
2016/06/12 Javascript
将List对象列表转换成JSON格式的类实现方法
2016/07/04 Javascript
React组件生命周期详解
2017/07/03 Javascript
js获取css的各种样式并且设置他们的方法
2017/08/22 Javascript
使用node打造自己的命令行工具方法教程
2018/03/26 Javascript
Vue+abp微信扫码登录的实现代码示例
2020/01/06 Javascript
解决vue 给window添加和移除resize事件遇到的坑
2020/07/21 Javascript
[01:16:12]完美世界DOTA2联赛PWL S2 FTD vs Inki 第一场 11.21
2020/11/23 DOTA
用Python制作检测Linux运行信息的工具的教程
2015/04/01 Python
Python实现的径向基(RBF)神经网络示例
2018/02/06 Python
python list删除元素时要注意的坑点分享
2018/04/18 Python
Python使用pyshp库读取shapefile信息的方法
2018/12/29 Python
python将图片转base64,实现前端显示
2020/01/09 Python
django orm模块中的 is_delete用法
2020/05/20 Python
详解python 支持向量机(SVM)算法
2020/09/18 Python
html5 datalist标签使用示例(自动完成组件)
2014/05/04 HTML / CSS
Html+Css+Jquery实现左侧滑动拉伸导航菜单栏的示例代码
2020/03/17 HTML / CSS
Moda Operandi官网:美国奢侈品电商,海淘秀场T台同款
2020/05/26 全球购物
事业单位绩效考核实施方案
2014/03/27 职场文书
材料采购员岗位职责
2015/04/03 职场文书
廉洁自律证明
2015/06/24 职场文书
有关保护环境的宣传标语100条
2019/08/07 职场文书
Mysql binlog日志文件过大的解决
2021/10/05 MySQL