JavaScript:如何获得 Private、Privileged、Public 和 Static 成员(属性和方法)【翻译+整理】
本文内容
- 背景
- 把我们的对象放在一起
- 添加一个私有(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 新手,已经回答了你可能的问题。
JavaScript:如何获得 Private、Privileged、Public 和 Static 成员(属性和方法)【翻译+整理】的更多相关文章
- javascript 构造函数类和原型 prototyp e定义的属性和方法的区别
1.把方法写在原型中比写在构造函数中消耗的内存更小,因为在内存中一个类的原型只有一个,写在原型中的行为可以被所有实例共享,实例化的时候并不会在实例的内存中再复制一份而写在类中的方法,实例化的时候会在每 ...
- 转: javascript动态添加、修改、删除对象的属性和方法
在其他语言中,对象一旦生成,就不可更改了,要为一个对象添加修改成员必须要在对应的类中修改,并重新实例化,而且程序必须经过重新编译.JavaScript 中却非如此,它提供了灵活的机制来修改对象的行为, ...
- javascript动态添加、修改、删除对象的属性与方法
在其他语言中,对象一旦生成,就不可更改了,要为一个对象添加修改成员必须要在对应的类中修改,并重新实例化,而且程序必须经过重新编译.JavaScript 中却非如此,它提供了灵活的机制来修改对象的行为, ...
- javascript——对象的概念——函数 1 (函数对象的属性和方法)
一.创建函数 函数是一种对象:Function类 是对象,可以通过 Function 实例化一个函数,不过最多的还是利用 function 来创建函数. 方式一:利用 Function类 来实例化函数 ...
- javascript中对象的每个实例都具有的属性和方法
- PHP中private、public、protected的区别详解
先简单粗俗的描述下:public 表示全局,类内部外部子类都可以访问:private表示私有的,只有本类内部可以使用:protected表示受保护的,只有本类或子类或父类中可以访问: 再啰嗦的解释下: ...
- JavaScript基础对象创建模式之私有属性和方法(024)
JavaScript没有特殊的语法来表示对象的私有属性和方法,默认的情况下,所有的属性和方法都是公有的.如下面用字面声明的对象: var myobj = { myprop: 1, getProp: f ...
- static 关键字详解 static方法调用非static属性和方法
静态的属性和方法在内存中的存放地址与非静态的是不同的,静态的是存放在static区,它意味着静态方法是没有this的,所以我们不可以从一个static方法内部发出对非static方法的调用.但是反之是 ...
- java基础64 JavaScript中的Arrays数组对象和prototype原型属性(网页知识)
1.Arrays数组对象的创建方式 方式一: var 变量名=new Array(); //创建一个长度为0的数组. 方式二: var 变量名=new Array(长度); //创建一个指定长度的数组 ...
随机推荐
- mexHttpBinding协议 【发布元数据终结点】
我们需要知道很多东西才能使用微软通信基础架构(WCF)来开发应用程序.尽管这本书已经试着囊括普通开发人员需要了解的WCF所有内容,也还是有一些内容没有讨论到.附录的主要目的是填充这些罅隙. 发布元数据 ...
- delphi下实现ribbon界面的方法(一)
http://www.cnblogs.com/shanmx/archive/2011/12/04/2275213.html
- 用delphi实现完美屏幕截图
可以截取layered窗口(包括透明窗口)的代码: procedure CaptureScreen(AFileName: string);const CAPTUREBLT = $40000000;v ...
- Java常用排序算法及性能测试集合
测试报告: Array length: 20000 bubbleSort : 573 ms bubbleSortAdvanced : 596 ms bubbleSortAdvanced2 : 583 ...
- OPTAUTH 两步验证详解
先贴图: 在对外网开放的后台管理系统中,使用静态口令进行身份验证可能会存在如下问题: (1) 为了便于记忆,用户多选择有特征作为密码,所有静态口令相比动态口令而言,容易被猜测和破解: (2) 黑客可以 ...
- apache路由端口配置
<VirtualHost *:80> ServerName a.com ProxyPreserveHost On ProxyRequests On ProxyPass / http://1 ...
- jquery获取table,遍历输出tr中各个td的内容(转载)
首先,依赖jquery.. 1 $('#btntb').click(function(){ 2 $('#tab tr').each(function(i){ // 遍历 tr 3 $(this).ch ...
- [Web 前端] CSS篇之3. 如何保持浮层水平垂直居中
原文链接](http://www.cnblogs.com/yaliu/p/5190957.html) 浮层水平垂直居中方法 (一)利用绝对定位与transform <div class=&quo ...
- Svg.js 图片加载
一.SVG.Image 1.创建和修改图片 var draw = SVG('svg1').size(300, 300); //SVG.Image 加载图片文件 var image = draw.ima ...
- maven配置sqlServer的依赖
配置sqlServer的依赖 <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifac ...