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 ...
随机推荐
- net发布的dll方法和类显示注释信息(字段说明信息)[图解]
自己发布的dll添加的另一个项目中突然没有字段说明信息了,给使用带来了很多的不便,原因是为了跨项目引用,所以导致不显示注释信息的,一下是解决这个问题的方法. 在要发布(被引用)的项目上右键 => ...
- 用Supervisord管理Python进程
http://feilong.me/2011/03/monitor-processes-with-supervisord Supervisord是用Python实现的一款非常实用的进程管理工具,类似于 ...
- [工具] GIF 动画每帧合并到一张 PNG
功能:将 GIF 动画每帧合并到一张 PNG 需求:配合 ImageMagick 图像处理软件. 下载:[工具]Gif2Png_Aone_1.0.0.zip 使用方法: 请到 ImageMagick ...
- 【C语言学习趣事】_32_平胸的尴尬,嫁不出去的姑娘
为什么写这篇文章呢? 为什么要弄这么个题目呢? 首先解释为什么用这个题目.这一切都要从那天在QQ群中的讨论说起,那天在群中,一个哥们问了一个关于(void)0 的问题.然后大家说到了 (void)0和 ...
- WebDriver多线程并发
要想多线程并发的运行WebDriver,必须同时满足2个条件,首先你的测试程序是多线程,其次需要用到Selenium Server.下载位置如下图: 下载下来后是一个jar包,需要在命令行中运行.里面 ...
- easyui datagrid 分页略解
easyui datagrid 本身自带了分页功能. 但是这个需要你自己控制. 在后台可以得到两个datagrid的参数,rows 和page.其中rows是每页要显示的个数,page是第几页.单纯的 ...
- 使用coding、daocloud和docker打造markdown纯静态博客
说起独立博客的技术演变,从数据库到纯文本放git是一大进步,从HTML到markdown又是一大进步. 解析技术有没有进步呢?既然markdown是纯文本了,再用PHP/Python/Ruby去实时解 ...
- 用css计算选中的复选框有几个
上代码: <!DOCTYPE html> <html> <head> <meta charset='UTF-8'> <title>计数< ...
- Photoshop如何实现UI自动切图?
切图严格来说并不是UI设计师的工作, 而是前端工程师的工作,指的是将UI设计师的设计(大部分为photoshop创建的PSD文件)转化为界面(网页或窗体等)所需要资源的过程.切图是衔接UI设计和应用程 ...
- browser.html – HTML 实现 Firefox UI
browser.html 是一个实验性的项目,用于证明一个概念:使用 HTML 重新实现 Firefox UI ,并作为一个应用程序.它是基于浏览器的 API ,并以浏览器的方式和系统的应用工作.即使 ...