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 相关文章推荐
jValidate 基于jQuery的表单验证插件
Dec 12 Javascript
getJSON调用后台json数据时函数被调用两次的原因猜想
Sep 29 Javascript
javascript实现详细时间提醒信息效果的方法
Mar 11 Javascript
JavaScript中解析JSON数据的三种方法
Jul 03 Javascript
JS组件系列之使用HTML标签的data属性初始化JS组件
Sep 14 Javascript
Bootstrap基本插件学习笔记之轮播幻灯片(23)
Dec 08 Javascript
Vue概念及常见命令介绍(1)
Dec 08 Javascript
JavaScript之RegExp_动力节点Java学院整理
Jun 29 Javascript
浅析Angular19 自定义表单控件
Jan 31 Javascript
AngularJs中$cookies简单用法分析
May 30 Javascript
js针对图片加载失败的处理方法分析
Aug 24 Javascript
解决Layui 表格自适应高度的问题
Nov 15 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自动生成月历代码
2006/10/09 PHP
PHP内核探索:变量存储与类型使用说明
2014/01/30 PHP
php截取字符串函数substr,iconv_substr,mb_substr示例以及优劣分析
2014/06/10 PHP
php异步多线程swoole用法实例
2014/11/14 PHP
thinkphp制作404跳转页的简单实现方法
2016/09/22 PHP
laravel实现上传图片,并且制作缩略图,按照日期存放的代码
2019/10/16 PHP
jQeury淡入淡出需要注意的问题
2010/09/08 Javascript
JavaScript具有类似Lambda表达式编程能力的代码(改进版)
2010/09/14 Javascript
细说浏览器特性检测(2)-通用事件检测
2010/11/05 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
2013/12/13 Javascript
字符串反转_JavaScript
2016/04/28 Javascript
限制只能输入数字的实现代码
2016/05/16 Javascript
jQuery dataTables与jQuery UI 对话框dialog的使用教程
2016/09/02 Javascript
vue实现动态数据绑定
2017/04/28 Javascript
详解开发react应用最好用的脚手架 create-react-app
2018/04/24 Javascript
python使用reportlab画图示例(含中文汉字)
2013/12/03 Python
python发送伪造的arp请求
2014/01/09 Python
Python中new方法的详解
2019/01/15 Python
python2.7使用plotly绘制本地散点图和折线图
2019/04/02 Python
python3中celery异步框架简单使用+守护进程方式启动
2021/01/20 Python
EMU Australia澳大利亚官网:澳大利亚本土雪地靴品牌
2019/07/24 全球购物
Hotels.com韩国:海外国内旅行所需的酒店和住宿预订网站
2020/05/08 全球购物
你所在的项目是如何确定版本号的
2015/12/28 面试题
一份婚庆公司创业计划书
2014/01/11 职场文书
售房协议书范本2014
2014/10/23 职场文书
信访维稳承诺书
2015/05/04 职场文书
2015年社区居委会工作总结
2015/05/18 职场文书
千手观音观后感
2015/06/03 职场文书
2015年全民创业工作总结
2015/07/23 职场文书
基于Redis实现分布式锁的方法(lua脚本版)
2021/05/12 Redis
HTML+VUE分页实现炫酷物联网大屏功能
2021/05/27 Vue.js
MySQL 时间类型的选择
2021/06/05 MySQL
js基础语法与maven项目配置教程案例
2021/07/15 Javascript
SpringBoot实现quartz定时任务可视化管理功能
2021/08/30 Java/Android
尝试使用Python爬取城市租房信息
2022/04/12 Python
Redis 限流器
2022/05/15 Redis