原文地址:

http://frugalcoder.us/post/2010/02/11/js-classes.aspx

Classy JavaScript - Best Practices

11. February 2010 13:26

Okay, so you really want to be able to have some of your JavaScript methods to have access to a variable that is private, but maintains state between calls. The first piece of knowledge, is that you can have the contents of a function execute itself at runtime.

1.(function(){ /*Your actions here*/ })();

This is a very common method of defining complex classes and libraries, that can have their own variables or methods that aren't otherwise available to the object model outside this closure. When you utilize "this" within the function's closure it will be default to the global object, which in the Browser DOM is "window".

1.(function(){
2.this.test = "Test Value";
3.})();
4.alert(test); //alerts "Test Value"

Usually when creating libraries in JavaScript it's a good idea to create namespaces for your library. Below I am going to use a classic example for defining a namespace of My.Namespace. There are helper methods out there that will walk a chain from a literal string of "My.Namespace", but I'm showing it in raw script.

1.if (typeof My == 'undefined')
2.My = {};
3.if (typeof My.Namespace == 'undefined')
4.My.Namespace = {};

By combining the above method, and using the Function.prototype.call method on your anonymous function, you can call the function with "this" set to your namespace. I'll be implementing a class called "SomeClass" within "My.Namespace" below. I'll also be showing how to create private static members and methods, allong with public static methods, and instance methods.

01.//begin private closure
02.(function(){
03. 
04.//this is a private static member that is only available in this closure
05.var instances = 0;
06. 
07.//this is a private static method that can be used internally
08.function _incrementInstances() {
09.instances++;
10.}
11. 
12.//Define SomeClass (js uses functions as class constructors, utilized with the "new" keyword)
13.this.SomeClass = function(options) {
14.//if the function is called directly, return an instance of SomeClass
15.if (!(this instanceOf SomeClass))
16.return new SomeClass(options);
17. 
18.//call static method
19._doSomething();
20. 
21.//handle the options initialization here
22.}
23. 
24.//create a public static method for SomeClass
25.this.SomeClass.getInstanceCount = function() {
26.return instances; //returns the private static member value
27.}
28. 
29.//create an instance method for SomeClass
30.this.SomeClass.prototype.doSomething = function() {
31./*Do Something Here*/
32.}
33. 
34.//end private closure then run the closure, localized to My.Namespace
35.}).call(My.Namespace);

The above is an example of best practices for defining a Class within a given namespace. From here, you can instantiate an instance of "My.NameSpace.SomeClass" and utilize the public methods exposed.

01.//instantiate a SomeClass instance
02.var sc = new My.Namespace.SomeClass({/* options go here */});
03. 
04.//call SomeClass as a function, which will return an instance
05.//  defined above via "(!(this instanceOf SomeClass))"
06.var sc = My.Namespace.SomeClass({/* options */});
07. 
08.//view the instance count, which uses a public static method
09.//  to return a private static member.
10.alert(My.Namespace.SomeClass.getInstanceCoun());

From here, you may be thinking to yourself, that's a lot of typing. This is where aliasing can come in handy, in this example inside a closure of course.

01.(function(){
02.//alias My.NameSpace
03.var m = My.NameSpace
04. 
05.//bad form assigning onload internally,
06.//  but that'll be for another post on event binding
07.//  Also, we could use "this.onload" but using window directly is more obvious here.
08.window.onload = function() {
09.//attach an instance of My.NameSpace.SomeClass instance to window.
10.window.sc = new m.SomeClass({}); //no long namespace name here :)
11.}
12. 
13.})();

Hopefully this post will be helpful in utilizing some privacy with your classes, and using namespaces to prevent naming collisions with other classes, and libraries.

javascript 私有方法的实现的更多相关文章

  1. JavaScript 类私有方法的实现

    一:将私有方法移出模块,因为模块内部的所有方法都是对外可见的. class Widget { foo (baz) { bar.call(this, baz); } // ... } function ...

  2. JavaScript中子类调用父类方法的实现

    一.前言 最近在项目中,前端框架使用JavaScript面向对象编程,遇到了诸多问题,其中最典型的问题就是子类调用父类(super class)同名方法,也就是如C#中子类中调用父类函数base.** ...

  3. JavaScript内置一些方法的实现原理--new关键字,call/apply/bind方法--实现

    先学习下new操作符吧 new关键字调用函数的心路历程: 1.创建一个新对象 2.将函数的作用域赋给新对象(this就指向这个对象) 3.执行函数中的代码 4.返回这个对象 根据这个的思路,来实现一个 ...

  4. Atitit paip.对象方法的实现原理与本质.txt

    Atitit paip.对象方法的实现原理与本质.txt 对象方法是如何实现的1 数组,对象,字典1 对象方法是如何实现的 这显然是一个对象方法调用.但对象方法是如何实现的呢?在静态语言中,因为有编译 ...

  5. OC:属性的内部实现原理、dealloc内释放实例变量、便利构造器方法的实现原理、collection的内存管理

    代码: // // main.m #import <Foundation/Foundation.h> #import "Person.h" #import " ...

  6. 基于原生JS的jsonp方法的实现

    基于原生JS的jsonp方法的实现 jsonp,相信大家并不陌生,是在js异步请求中解决跨域的方法之一,原理很简单,有不清楚的同学可以google下,这里就补详细解释了.在Jquery库中,jQuer ...

  7. 关于Java中hashCode方法的实现源码

    首先来看一下String中hashCode方法的实现源码. public int hashCode() { int h = hash; if (h == 0 && value.leng ...

  8. js中的bind方法的实现方法

    js中目前我遇见的改变作用域的5中方法:call, apply, eval, with, bind. var obj = { color: 'green' } function demo () { c ...

  9. Salesforce LWC学习(十五) Async 以及 Picklist 公用方法的实现

    本篇参考:salesforce 零基础学习(六十二)获取sObject中类型为Picklist的field values(含record type) https://developer.salesfo ...

随机推荐

  1. STM8S TIM4 初始化设置

    #define TIM4_DIV1 (unsigned char)0 #define TIM4_DIV2 (unsigned char)1 #define TIM4_DIV4 (unsigned ch ...

  2. [置顶] 让我爱恨的ThinkPHP Relation

    还记得第一次用ThinkPHP的relation,做了一个关联查询,觉得特别好用.有那么一天尝试着用关联插入,怎么插,都插不进,我插,我擦! 后来在龙哥的指点下算是成功的实践了一次,后来怎么用都不顺, ...

  3. 移植rtmpdump(librtmp)到android

    编译环境:(rtmpdump-master.zip和Polar SSL版本已经打包上传,具体路径在http://download.csdn.net/detail/gyley2/5721061) win ...

  4. Ubuntu12.10 下搭建基于KVM-QEMU的虚拟机环境(三)

    原则上来说,qemu, libvirt, libusb, usbredir, spice等都可以通过 apt-get install的方式从Ubuntu源在线安装.但是这样如果碰到一点问题,就比较难办 ...

  5. idea下git版本回退

    首先选中项目名,然后 ,show history, copy你想要回退版本的reversion number, ,然后在branches里check out你想要回退的版本

  6. 使用Unity创建塔防游戏(Part2)

    How to Create a Tower Defense Game in Unity – Part 2 原文地址:https://www.raywenderlich.com/107529/unity ...

  7. oc之里氏替换原则

    1. 里氏替换原则. LSP 子类对象可以替换父类对象的位置,并且程序的功能不受影响. 为什么? 1). 指针是1个父类类型,但是我们确给了指针1个子类对象的地址. 这样做当然是可以的,因为你要1个父 ...

  8. ELK采集之nginx 之高德地图出城市IP分布图

    1.采用拓扑: 角色扮演: Agent:采用logstash,IP:192.168.10.7 Redis队列: IP:192.168.10.100 Indexer:logstash,IP:192.16 ...

  9. iOS开发-OC语言 (三)字符串

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 24.0px "PingFang SC" } p ...

  10. Redmine管理项目2-邮件通知

    下面是为Redmine配置邮件通知 配置文件 config/configuration.yml 是 Redminde 的配置文件,里面有非常多的选项,邮件通知.附件保存地址. SCM .rmagick ...