本文内容

  • 背景
  • 把我们的对象放在一起
    • 添加一个私有(Private)的属性
    • 添加一个特权(Privileged)的方法
    • 添加一个公共(Public)的属性和方法
    • 添加一个静态(Static)的属性
    • 我们自己的完整对象
    • 创建一个实例对象并检查可访问性
  • 结论

其实,写 JavaScript 代码可以不用“面向对象”的方式,这不是必需的,但多年的工程实践表明,面向对象的确很好地解决问题了,代码变得更优雅(更通用,更容易扩展和维护),虽然 JavaScript 不支持面向对象,但可以模拟它。因此,开发人员们就想,既然面向对象还不错,那就尝试把之前在面向对象中取得经验和成就应用到 JavaScript 的代码上。促使开发人员这么想也这么干,也是出于现实考虑,不得已而为之,随着项目中的 JavaScript 代码越来越庞大,如每个页面有 10 万行代码很常见,而 gmail 有 44.3 万行,不设计、不规划一下是不行了。为了达到这个目的,你需要先知道 JavaScript 的东西很多,比如,作用域、作用域链、闭包、对象、实例对象、继承等等,并把 JavaScript 和面向对象编程对应起来,特别是对于像我,之前用其他语言从事面向对象开发的人来说。

如果你了解 JavaScript 的继承——如何和为什么,以及 JavaScript 的作用域和闭包,那么,我们就可以把这些知识结合在一起,讨论 JavaScript 对象的私有(private)、特权(privileged)、公共(public )和静态(static )成员(属性和方法)JavaScript中的对象。

 

背景


对于来自面向对象背景的开发人员来说,定义和使用这些成员对所有代码来说都是关键。但对使用 JavaScript 的人来说,也许不需要这样,可如果你知道如何将“面向对象”应用到 JavaScript 上,会使你的代码更通用。

 

把我们的对象放在一起


我们将把讨论的内容放在构造函数对象里,然后你通过 new 关键字创建一个新的实例对象。让我们先从一个空的对象开始:

        // Constructor
        function Kid(name) {
            // Empty, for now
        }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

现在,你可以用如下方式创建很多 Kid  实例对象:

        var kenny = new Kid("Kenny");

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

添加一个私有(Private)的属性

在我们学习 JavaScript 作用域和闭包中,函数内声明的一个变量只能在函数内可用(这是局部变量)。因此,如果我们想 kid 对象有一个私有(private)属性,我们可以这样做:

        // Constructor
        function Kid(name) {
            // Private
            var idol = "Paris Hilton";
        }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

idol 属性将只对 Kid  函数/对象内可用。注意:idol  属性前边的 var 关键字。

添加一个特权(Privileged)的方法

特权(privileged)方法是一种能够访问私有(private)属性的方法,而同时向外面公开它自己(在 JavaScript 中,也由于 JavaScript 作用域和闭包)。你可以删除或替换一个特权方法,但你不能改变它的内容。如特权方法返回一个私有属性的值:

        // Constructor
        function Kid(name) {
            // Private
            var idol = "Paris Hilton";
 
            // Privileged
            this.getIdol = function () {
                return idol;
            };
        }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

添加一个公共(Public)的属性和方法

现在,我们有了私有属性,和从外边访问它的特权方法,让我们来看看很基本的公共属性和公共方法:

        // Constructor
        function Kid(name) {
            // Public
            this.name = name;
            this.getName = function () {
                return this.name;
            };
        }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

公共属性对任何调用都是可用的,像 getName 方法。

但是,正如在下面代码提到的,与其他类型相比,公共方法的推荐方式是使用原型(prototype)方法,修改上面代码后,例如:

        // Constructor
        function Kid(name) {
            // Public
            this.name = name;
        }
        Kid.prototype.getName = function () {
            return this.name;
        };

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

添加一个静态(Static)的属性

静态成员被所有的实例对象和它自己所共享(即 Kid 对象),静态成员只存储在一个地方。这意味着,它的值不会被继承到其下面的实例对象:

        // Constructor
        function Kid(name) {
            // Constructor code
        }
 
        // Static property
        Kid.town = "South Park";

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

我们自己的完整对象

在我们尝试访问对象的属性和方法前,看一下这个完整的对象:

        // Constructor
        function Kid(name) {
            // Private
            var idol = "Paris Hilton";
 
            // Privileged
            this.getIdol = function () {
                return idol;
            };
 
            // Public
            this.name = name;
        }
 
        // Public
        Kid.prototype.getName = function () {
            return this.name;
        };
 
        // Static property
        Kid.town = "South Park";

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

创建一个实例对象并检查可访问性


现在是测试这些不同方法在实际中是如何工作的了。我们先创建一个 Kid 实例对象,然后,测试我们得到什么不同值。测试机器结果如下所示:

        // Create a new instance
        var cartman = new Kid("Cartman");
 
        // Access private property
        cartman.idol; // undefined
 
        // Access privileged method
        cartman.getIdol(); // "Paris Hilton"
 
        // Access public property
        cartman.name; // "Cartman"
 
        // Access public method
        cartman.getName(); // "Cartman"
 
        // Access static property on an instance
        cartman.town; // undefined
 
        // Access static property on the constructor object
        Kid.town; // "South Park"

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 

结论


当涉及对象和其成员的时候,希望你用适当的方式去选择。另外,对于之前用其他语言从事面向对象编程的 JavaScript 新手,已经回答了你可能的问题。

 

下载 Demo

JavaScript:如何获得 Private、Privileged、Public 和 Static 成员(属性和方法)【翻译+整理】的更多相关文章

  1. javascript 构造函数类和原型 prototyp e定义的属性和方法的区别

    1.把方法写在原型中比写在构造函数中消耗的内存更小,因为在内存中一个类的原型只有一个,写在原型中的行为可以被所有实例共享,实例化的时候并不会在实例的内存中再复制一份而写在类中的方法,实例化的时候会在每 ...

  2. 转: javascript动态添加、修改、删除对象的属性和方法

    在其他语言中,对象一旦生成,就不可更改了,要为一个对象添加修改成员必须要在对应的类中修改,并重新实例化,而且程序必须经过重新编译.JavaScript 中却非如此,它提供了灵活的机制来修改对象的行为, ...

  3. javascript动态添加、修改、删除对象的属性与方法

    在其他语言中,对象一旦生成,就不可更改了,要为一个对象添加修改成员必须要在对应的类中修改,并重新实例化,而且程序必须经过重新编译.JavaScript 中却非如此,它提供了灵活的机制来修改对象的行为, ...

  4. javascript——对象的概念——函数 1 (函数对象的属性和方法)

    一.创建函数 函数是一种对象:Function类 是对象,可以通过 Function 实例化一个函数,不过最多的还是利用 function 来创建函数. 方式一:利用 Function类 来实例化函数 ...

  5. javascript中对象的每个实例都具有的属性和方法

  6. PHP中private、public、protected的区别详解

    先简单粗俗的描述下:public 表示全局,类内部外部子类都可以访问:private表示私有的,只有本类内部可以使用:protected表示受保护的,只有本类或子类或父类中可以访问: 再啰嗦的解释下: ...

  7. JavaScript基础对象创建模式之私有属性和方法(024)

    JavaScript没有特殊的语法来表示对象的私有属性和方法,默认的情况下,所有的属性和方法都是公有的.如下面用字面声明的对象: var myobj = { myprop: 1, getProp: f ...

  8. static 关键字详解 static方法调用非static属性和方法

    静态的属性和方法在内存中的存放地址与非静态的是不同的,静态的是存放在static区,它意味着静态方法是没有this的,所以我们不可以从一个static方法内部发出对非static方法的调用.但是反之是 ...

  9. java基础64 JavaScript中的Arrays数组对象和prototype原型属性(网页知识)

    1.Arrays数组对象的创建方式 方式一: var 变量名=new Array(); //创建一个长度为0的数组. 方式二: var 变量名=new Array(长度); //创建一个指定长度的数组 ...

随机推荐

  1. cocos2d-x学习资源汇总

      http://blog.csdn.net/akof1314 http://blog.csdn.net/bill_man/ http://blog.csdn.net/fylz1125/ MoonWa ...

  2. 酷播迷你flv,mp4网页视频播放器(CuPlayerMini)V2.2版[经典黑]演示实例

    酷播迷你flv,mp4网页视频播放器(CuPlayerMini)V2.2版[经典黑]演示实例 http://www.cuplayer.com/cu/FreeDown/

  3. C#网络编程技术FastSocket实战项目演练

    一.FastSocket课程介绍 .NET框架虽然微软提供了socket通信的类库,但是还有很多事情要自己处理,比如TCP协议需要处理分包.组包.粘包.维护连接列表等,UDP协议需要处理丢包.乱序,而 ...

  4. 如何快速分析一款ios软件或需求的大流程,然后在业务层实现,不牵扯到界面?

    如何快速分析一款ios软件或需求的大流程,然后在业务层实现,不牵扯到界面?

  5. iOS 字符串 中包含 % 百分号的方法

    百分号的转换,NSString中需要格式化的字符串中百分号使用%%表示,而char*中百分号也是使用%%表示. 例如:NSLog(@"%%%@%%",@"hello&qu ...

  6. springboot实现服务器端消息推送(websocket + sockjs + stomp)

    服务器端推送技术在web开发中比较常用,可能早期很多人的解决方案是采用ajax向服务器轮询消息,这种方式的轮询频率不好控制,所以大大增加了服务器的压力,后来有了下面的方案:当客户端向服务器发送请求时, ...

  7. c++ strcmp strcpy sprintf

  8. BI 可视化

    1. Blackbird: Open Source JavaScript Logging Utility Blackbird 是一款非常酷的 JavaScript 调试工具,带有一个漂亮的界面显示和过 ...

  9. log4j生成有日期的日志文件名

    有任务需求,需要输出日志为 文件名+日期格式作为文件保存. 解决方法很简单: log4j.appender.file=org.apache.log4j.DailyRollingFileAppender ...

  10. Spring4+quartz2集群借助邮箱或是短信实现生日的农历提醒(Quartz实现农历、阴历、公历生日提醒)

    自己记性差,除了老婆.老大和自己的生日以外,一直记不住亲朋好友的生日,长辈们的生日基本上又都是用农历来算,公历的话,直接用Quartz设置循环提醒,农历就没辙了,每每搞的自己很尴尬,需要别人来提醒自己 ...