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 对Cookie 操作的封装小结
Dec 31 Javascript
JavaScript 读取元素的CSS信息的代码
Feb 07 Javascript
基于JQuery实现CheckBox全选全不选
Jun 27 Javascript
提示$ is not defined错误分析及解决
Apr 09 Javascript
jquery为页面增加快捷键示例
Jan 31 Javascript
js字符串操作方法实例分析
May 06 Javascript
对象转换为原始值的实现方法
Jun 06 Javascript
Vue实现todolist删除功能
Jun 26 Javascript
layui从数据库中获取复选框的值并默认选中方法
Aug 15 Javascript
ES6 fetch函数与后台交互实现
Nov 14 Javascript
vue 父组件给子组件传值子组件给父组件传值的实例代码
Apr 15 Javascript
解决echarts 一条柱状图显示两个值,类似进度条的问题
Jul 20 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
计数器详细设计
2006/10/09 PHP
Ajax+PHP 边学边练 之二 实例
2009/11/24 PHP
探讨PHP JSON中文乱码的解决方法详解
2013/06/06 PHP
jQuery让控件左右移动的三种实现方法
2013/09/08 Javascript
JavaScript使用HTML5的window.postMessage实现跨域通信例子
2014/04/11 Javascript
使用原生js写的一个简单slider
2014/04/29 Javascript
页面刷新时记住滚动条的位置jquery代码
2014/06/17 Javascript
两种方法基于jQuery实现IE浏览器兼容placeholder效果
2014/10/14 Javascript
jquery实现的简单二级菜单效果代码
2015/09/22 Javascript
解决js函数闭包内存泄露问题的办法
2016/01/25 Javascript
js只执行1次的函数示例
2016/07/20 Javascript
Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#‘的解决方法
2017/06/17 Javascript
使用vs code开发Nodejs程序的使用方法
2017/09/21 NodeJs
iview table render集成switch开关的实例
2018/03/14 Javascript
Vue多系统切换实现方案
2018/06/05 Javascript
Vue常用传值方式、父传子、子传父及非父子实例分析
2020/02/24 Javascript
Vue 3.0 全家桶抢先体验
2020/04/28 Javascript
解决VUEX的mapState/...mapState等取值问题
2020/07/24 Javascript
JS变量提升及函数提升实例解析
2020/09/03 Javascript
[01:29]2014DOTA2展望TI 剑指西雅图DK战队专访
2014/06/30 DOTA
Python线程指南详细介绍
2017/01/05 Python
Python爬虫包BeautifulSoup简介与安装(一)
2018/06/17 Python
TensorFlow的reshape操作 tf.reshape的实现
2020/04/19 Python
Numpy数组的广播机制的实现
2020/11/03 Python
佳能德国网上商店:Canon德国
2017/03/18 全球购物
叙述DBMS对数据控制功能有哪些
2016/06/12 面试题
室内设计自我鉴定
2013/10/15 职场文书
同事打架检讨书
2014/02/04 职场文书
高中军训感言400字
2014/02/24 职场文书
宣传口号大全
2014/06/16 职场文书
2014年艾滋病防治工作总结
2014/12/10 职场文书
汽车质检员岗位职责
2015/04/08 职场文书
基层组织建设年活动总结
2015/05/09 职场文书
教你怎么用python selenium实现自动化测试
2021/05/27 Python
Python类方法总结讲解
2021/07/26 Python
vue本地构建热更新卡顿的问题“75 advanced module optimization”完美解决方案
2022/08/05 Vue.js