JavaScript Accessor实现说明


Posted in Javascript onDecember 06, 2010

第一种算是比较常见了,通过闭包Store Value从而实现accessor,适用于所有浏览器.

function Sandy(val){ 
var value = val; 
this.getValue = function(){ 
return value; 
}; 
this.setValue = function(val){ 
value = val; 
}; 
} 
//usage 
var sandy = new Sandy("test"); 
sandy.value 
// => undefined 
sandy.setValue("test2") 
sandy.getValue

下面是JavaScript权威指南(中文第五版)中P152页使用闭包的一个例子.
function makeProperty(o, name, predicate) { 
var value; //This is property value; //The setter method simply returns the value 
o['get' + name] = function() { return value;}; 
//The getter method stores the value or throws an exception if 
//the predicate rejects the value 
o['set' + name] = function(v) { 
if (predicate && !predicate(v) { 
throw 'set' + name + ': invalid value ' + v; 
} else { 
value = y; 
} 
} 
} 
//The following code demenstrates the makeProperty() method 
var o = {}; // Here is an empty object 
//Add property accessor methods getName and setName 
//Ensure that only string values are allowed 
makeProperty(o, 'Name', function(x) { return typeof x == 'string'; }); 
o.setName('Frank'); 
//Set the property value; 
print(o.getName()); 
//Get the property value 
o.setName(0); //Try to set a value of the wrong type

第二种方法是使用__defineSetter__与__defineGetter__来实现accessor,看下划线就知道它们并非标准,适用于Firefox 2.0+, Safari 3.0+, Google Chrome 1.0+ 和 Opera 9.5+ ,方法使用见MDN.
function Sandy(val){ 
var value = val, 
_watch = function(newVal) { 
console.log('val is Changed to : ' + newVal); 
} this.__defineGetter__("value", function(){ 
return value; 
}); 
this.__defineSetter__("value", function(val){ 
value = val; 
_watch(val); 
}); 
} 
var sandy = new Sandy("test"); 
sandy.value 
// => test 
sandy.value = "test2"; 
// => 'val is Changed to : test2' 
sandy.value 
// => "test2"

 除了__defineG/Setter__外, 你还可以使用'set'、'get'关键字在在原型对象上定义accessor,对于单个对象同样适用, 适用于Firefox 2.0+, Safari 3.0+, Google Chrome 1.0+ 和 Opera 9.5+.
function Sandy(val){ 
this.value = val; 
} Sandy.prototype = { 
get value(){ 
return this._value; 
}, 
set value(val){ 
this._value = val; 
} 
}; 
//Or 
var sandy = { 
'_value' : 'sandy', 
get value() { 

return this._value; 
}, 
set value(val) { 

this._value = val; 
} 
}

最后一种方法,用到了Object的静态方法defineProperty,作用于单个对象,该方法应该属于ES5的范畴了,目前似乎只有Chrome 支持这种方法,其实Ie8也支持,但操作对象仅限于Dom节点(Dom node),见IEBlog,该方法的使用见MDN.
var sandy = {}, rValue; 
Object.defineProperty(sandy, 'value' , 
{ 
'set' : function(val) { 
rValue = val; 
}, 
'get' : function() { 
return rValue; 
}, 
'enumerable' : true, 
'configurable' : true 
} 
) 
//Ie8+ 
Object.defineProperty(document.body, "description", { 
get : function () { 
return this.desc; 
}, 
set : function (val) { 
this.desc = val; 
} 
}); 
document.body.description = "Content container"; 
// document.body.description will now return "Content container"

‘enumerable','configuralbe' 属于ES5规范中的Property Attributes(属性特性),在这里就不做讨论了,有兴趣的Google或者直接去看ES5的文档. ^ ^
Javascript 相关文章推荐
JS 判断代码全收集
Apr 28 Javascript
jQuery的实现原理的模拟代码 -1 核心部分
Aug 01 Javascript
原生JS和JQuery动态添加、删除表格行的方法
May 28 Javascript
js+html5绘制图片到canvas的方法
Jun 05 Javascript
jQuery zTree加载树形菜单功能
Feb 25 Javascript
js实现select选择框效果及美化
Aug 19 Javascript
JavaScript递归算法生成树形菜单
Aug 15 Javascript
基于vue2实现上拉加载功能
Nov 28 Javascript
mint-ui 时间插件使用及获取选择值的方法
Feb 09 Javascript
Vue使用json-server进行后端数据模拟功能
Apr 17 Javascript
原生js实现3D轮播图
Mar 21 Javascript
Vue两种组件类型:递归组件和动态组件的用法
Aug 06 Javascript
关于Javascript模块化和命名空间管理的问题说明
Dec 06 #Javascript
javascript处理table表格的代码
Dec 06 #Javascript
菜鸟javascript基础资料整理3 正则
Dec 06 #Javascript
菜鸟javascript基础资料整理2
Dec 06 #Javascript
菜鸟javascript基础整理1
Dec 06 #Javascript
js 上传图片预览问题
Dec 06 #Javascript
兼容IE和FF的js脚本代码小结(比较常用)
Dec 06 #Javascript
You might like
全文搜索和替换
2006/10/09 PHP
zf框架的registry(注册表)使用示例
2014/03/13 PHP
php递归删除指定文件夹的方法小结
2015/04/20 PHP
PHP实现微信网页授权开发教程
2016/01/19 PHP
JQuery Ajax 跨域访问的解决方案
2010/03/12 Javascript
基于jquery实现的移入页面上空文本框时,让它变为焦点,移出清除焦点
2011/07/26 Javascript
两个数组去重的JS代码
2013/12/04 Javascript
如何将网页表格内容导入excel
2014/02/18 Javascript
jQuery简单tab切换效果实现方法
2015/04/08 Javascript
判断访客终端类型集锦
2015/06/05 Javascript
使用pcs api往免费的百度网盘上传下载文件的方法
2016/03/17 Javascript
使用BootStrap实现表格隔行变色及hover变色并在需要时出现滚动条
2017/01/04 Javascript
iconfont的三种使用方式详解
2018/08/05 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
2018/08/25 Javascript
基于openlayers实现角度测量功能
2020/09/28 Javascript
[52:07]完美世界DOTA2联赛PWL S3 LBZS vs access 第二场 12.10
2020/12/13 DOTA
浅析Python中的join()方法的使用
2015/05/19 Python
python爬虫框架scrapy实现模拟登录操作示例
2018/08/02 Python
Python设计模式之命令模式原理与用法实例分析
2019/01/11 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
详解如何用TensorFlow训练和识别/分类自定义图片
2019/08/05 Python
Django配置文件代码说明
2019/12/04 Python
python 已知三条边求三角形的角度案例
2020/04/12 Python
python输出数学符号实例
2020/05/11 Python
python实现AdaBoost算法的示例
2020/10/03 Python
python GUI计算器的实现
2020/10/09 Python
python中Mako库实例用法
2020/12/31 Python
世界著名的顶级牛排:Omaha Steak(奥马哈牛排)
2016/09/20 全球购物
宝拉珍选官方旗舰店:2%水杨酸精华液,收缩毛孔粗大和祛痘
2018/07/01 全球购物
如何用Java实现列出某个目录下的所有子目录
2015/07/20 面试题
移动通信行业实习自我鉴定
2013/09/28 职场文书
学期研究性学习个人的自我评价
2014/01/09 职场文书
教师工作表现自我评价
2015/03/05 职场文书
html5移动端禁止长按图片保存的实现
2021/04/20 HTML / CSS
openstack中的rpc远程调用的方法
2021/07/09 Python
javascript中Set、Map、WeakSet、WeakMap区别
2022/12/24 Javascript