关于Getter与Setter大家一定不会陌生,下面简单介绍几种我所知道的在JavaScript中实现G/S的方法.
第一种算是比较常见了,通过闭包Store Value从而实现accessor,适用于所有浏览器.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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页使用闭包的一个例子.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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+.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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的文档. ^ ^
分类:
Front-End
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架