JavaScript Patterns 5.3 Private Properties and Methods
All object members are public in JavaScript.
var myobj = {
myprop : 1,
getProp : function() {
return this.myprop;
}
};
console.log(myobj.myprop);
// `myprop` is publicly accessible
console.log(myobj.getProp());
// getProp() is public too
The same is true when you use constructor functions to create objects.
// all members are still public:
function Gadget() {
this.name = 'iPod';
this.stretch = function() {
return 'iPad';
};
}
var toy = new Gadget();
console.log(toy.name);
// `name` is public
console.log(toy.stretch());
// stretch() is public
Private Members
Implement private members using a closure.
function Gadget() {
// private member
var name = 'iPod';
// public function
this.getName = function() {
return name;
};
}
var toy = new Gadget();
// `name` is undefined, it's private
console.log(toy.name);
// undefined
// public method has access to `name`
console.log(toy.getName());
// "iPod"
Privileged Methods
it’s just a name given to the public methods that have access to the private members (and hence have more privileges).
In the previous example, getName() is a privileged method because it has “special” access to the private property name.
Privacy Failures
• When you’re directly returning a private variable from a privileged method and this variable happens to be an object or array, then outside code can modify the private variable because it’s passed by reference.
function Gadget() {
// private member
var specs = {
screen_width : 320,
screen_height : 480,
color : "white"
};
// public function
this.getSpecs = function() {
return specs;
};
}
var toy = new Gadget(), specs = toy.getSpecs();
specs.color = "black";
specs.price = "free";
console.dir(toy.getSpecs());
/*
|
color |
"black" |
|
price |
"free" |
|
screen_height |
480 |
|
screen_width |
320 |
*/
Solutions
- Principle of Least Authority (POLA):
Return a new object containing only some of the data that could be interesting to the consumer of the object.
- Another approach, when you need to pass all the data, is to create a copy of the specs object, using a general-purpose object-cloning function.
Object Literal and Privacy
var myobj;
// this will be the object ( function() { // private members var name = "my, oh my"; // implement the public part // note -- no `var` myobj = { // privileged method getName : function() { return name; }
}; }()); var myobj = ( function() { // private members var name = "my, oh my"; // implement the public part return { getName : function() { return name; }
}; }()); myobj.getName();
// "my, oh my"
Prototypes and Privacy
One drawback of the private members when used with constructors is that they are recreated every time the constructor is invoked to create a new object. To solve this you can add common properties and methods to the prototype property of the constructor.
function Gadget() {
// private member
var name = 'iPod';
// public function
this.getName = function() {
return name;
};
}
Gadget.prototype = ( function() {
// private member
var browser = "Mobile Webkit";
// public prototype members
return {
getBrowser : function() {
return browser;
}
};
}());
var toy = new Gadget();
console.log(toy.getName());
// privileged "own" method
console.log(toy.getBrowser());
// privileged prototype method
Revealing Private Functions As Public Methods
var myarray;
(function () {
var astr = "[object Array]",
toString = Object.prototype.toString;
// private method
function isArray(a) {
return toString.call(a) === astr;
})
// private method
function indexOf(haystack, needle) {
var i = 0,
max = haystack.length;
for (; i < max; i += 1) {
if (haystack[i] === needle) {
return i;
}
}
return−1;
}
myarray = {
// public methods
isArray: isArray,
indexOf: indexOf,
inArray: indexOf
};
}());
myarray.isArray([1, 2]); // true
myarray.isArray({
0: 1
}); // false
myarray.indexOf(["a", "b", "z"], "z"); //
myarray.inArray(["a", "b", "z"], "z"); //
Now if something unexpected happens, for example, to the public indexOf(), the private indexOf() is still safe and therefore inArray()will continue to work:
myarray.indexOf = null; myarray.inArray(["a", "b", "z"], "z"); //
References:
JavaScript Patterns - by Stoyan Stefanov (O`Reilly)
JavaScript Patterns 5.3 Private Properties and Methods的更多相关文章
- JavaScript Patterns 4.8 Function Properties - A Memoization Pattern
Gets a length property containing the number of arguments the function expects: function func(a, b, ...
- JavaScript Patterns 5.4 Module Pattern
MYAPP.namespace('MYAPP.utilities.array'); MYAPP.utilities.array = (function () { // dependencies var ...
- JavaScript Patterns 6.7 Borrowing Methods
Scenario You want to use just the methods you like, without inheriting all the other methods that yo ...
- JavaScript Patterns 6.5 Inheritance by Copying Properties
Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) ...
- JavaScript Patterns 7.1 Singleton
7.1 Singleton The idea of the singleton pattern is to have only one instance of a specific class. Th ...
- OOP in JS Public/Private Variables and Methods
Summary private variables are declared with the 'var' keyword inside the object, and can only be acc ...
- JavaScript Patterns 6.6 Mix-ins
Loop through arguments and copy every property of every object passed to the function. And the resul ...
- JavaScript Patterns 6.4 Prototypal Inheritance
No classes involved; Objects inherit from other objects. Use an empty temporary constructor function ...
- JavaScript Patterns 6.3 Klass
Commonalities • There’s a convention on how to name a method, which is to be considered the construc ...
随机推荐
- c#使用WebClient登录网站抓取登录后的网页
C#登录网站实际上就是模拟浏览器提交表单,然后记录浏览器响应返回的会话Cookie值,再次发送请求时带着这个会话cookie值去请求就可以实现模拟登录的效果了. 如下类CookieAwareWebCl ...
- Sqlserver2005日志文件太大,使其减小的方法
Sqlserver2005日志文件太大,使其减小的方法: 运行下面的三行 dbName为数据库名: backup log dbNamewith NO_LOG backup log dbNamewith ...
- C# ~ 从 XML 到 Linq 到 Linq to XML
.XML 可扩展标记语言 (Extensible Markup Language), 标记 (markup) 是关键部分,是标准通用标记语言 (Standard Generalized Markup ...
- 半连通分量--Tarjan/Kosaraju算法
一个有向图称为半连通(Semi-Connected),满足:对于图中任两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. 若满足,则称G’是G的一个导出子图. 若G’是G的导出子图,且G’半 ...
- 组件Newtonsoft.Json实现object2json转换
很多情况下,我们需要把数据类型做一些转换,供其它外部的子系统调用. 最为典型的是生成json格式供javascript作调用. 现成的组件Newtonsoft.Json可以实现object2json之 ...
- .NET invoke NetSuite Restlet
Please indicate the source if you need to repost. Restlet allows programmers to use the http request ...
- JPA一对多循环引用的解决
说是解决,其实不是很完美的解决的,写出来只是想记录一下这个问题或者看一下有没有哪位仁兄会的,能否知道一二. 下面说说出现问题: 问题是这样的,当我查询一个一对多的实体的时候,工具直接就爆了,差不多我就 ...
- Servlet生命周期及工作原理
1 Servlet生命周期Servlet 生命周期:Servlet 加载--->实例化--->服务--->销毁. init():在Servlet的生命周期中,仅执行一次init()方 ...
- 高性能文件缓存key-value存储—Redis
1.高性能文件缓存key-value存储-Memcached 2.ASP.NET HttpRuntime.Cache缓存类使用总结 备注:三篇博文结合阅读,简单理解并且使用,如果想深入学习,请多参考文 ...
- CountUp.js – 让数字以非常有趣的动画方式显示
CountUp.js 无依赖的.轻量级的 JavaScript 类,可以用来快速创建以一种更有趣的动画方式显示数值数据.尽管它的名字叫 countUp,但其实可以在两个方向进行变化,这是根据你传递的 ...