zoukankan      html  css  js  c++  java
  • javascript 私有方法的实现

    原文地址:

    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.

  • 相关阅读:
    代码整洁之道它山之玉可以重构:身份证号码解析、验证工具(第一天)
    这也是C#代码吗 代码阅读性进阶:测试文档化
    它山之玉可以重构:身份证号码解析、验证工具(第三天)
    它山之玉可以重构:身份证号4(第四天)
    自己动手写压力测试三剑客HttpClient+Async+Parallel
    三层架构,够不够DDD眼中的三层(附C#源代码实现)
    百般武艺为哪般再谈业务域的核心地位
    深入浅出裸测之道单元测试的单元化
    它山之玉可以重构:身份证号码解析、验证工具(第二天)
    重构之重与敏捷之轻身份证号重构回顾
  • 原文地址:https://www.cnblogs.com/oxspirt/p/4487355.html
Copyright © 2011-2022 走看看