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 ...
随机推荐
- mvc jquery 修改 viewbag
[HttpGet] public ActionResult Modify(int id) { Books mod=db.Books.Where(b = ...
- jquery表单对象属性选择器
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- MultiLine Text光标停留在第一行
MultiLine Text是多行文本,默认设置下,光标是停留在控件中间的,很不好看. 解决的方法是设置属性android:gravity="top",这样光标就会停留在第一行.
- ThinkCMF-上传多个图片源码解读
关键函数: /** * 多图上传 * @param dialog_title 上传对话框标题 * @param container_selector 图片容器 * @param item_tpl_wr ...
- virtualenvwrapper安装使用
安装 linux和mac下安装 pip install virutalenv virtualenvwrapper windows下安装 pip install virtualenvwrapper-wi ...
- [小北De编程手记] : Lesson 06 玩转 xUnit.Net 之 定义自己的FactAttribute
xUnit.Net本身提供了标记测试方法的标签Fact和Theory.在前面的文章<Lesson 02 玩转 xUnit.Net 之 基本UnitTest & 数据驱动>中,也对它 ...
- Java检测对象是否相等
关系运算符==和!=也适用于所有对象,但它们的含义通常会使初涉Java 领域的人找不到北.下面是一个例子: public class Equivalence { public static void ...
- Rational Rose :从用例图开始
前置条件:安装Rational Rose 2003 找开Rose工具,选择用例视图 Use Case View 先看看这个视图下面都有哪些工具,都能做一些什么: 下面详细说一下: 用例视图下面有工具 ...
- a标签的target属性
_blank 浏览器总在一个新打开.未命名的窗口中载入目标文档. _self 这个目标的值对所有没有指定目标的 <a> 标签是默认目标,它使得目标文档载入并显示在相同的框架或者窗口中作为源 ...
- 酷酷的jQuery classicAccordion 手风琴
在线实例 效果一 效果二 效果三 使用方法 手风琴ul li列表 <ul class="accordion"> <li> < ...