对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,那么如何在Javascript中利用封装这个特性呢?
我们会把现实中的一些事物抽象成一个Class并且把事物的属性(名词)作为Class的Property把事物的动作(动词)作为Class的methods。在面向对象的语言中(C#等)都会有一些关键字来修饰类或者属性(Private,public,protect),这些关键词描述了访问的权限,不多做解释。
我们来看看Javascript的易变的特性(我们还用上一次的例子):
01 |
var Man = function (name, age) { |
05 |
var Person = new Interface( "Person" , [ "GetName" , "GetAge" ]); |
06 |
Man.prototype = { GetName: function () { return this .Name; }, |
07 |
GetAge: function () { return this .Age; } |
09 |
var Gonn = new Man( "Gonn" , 25); |
11 |
Gonn.DisplayAll = function () { return "Name: " + this .GetName() + "; Age: " + this .GetAge() } |
12 |
alert(Gonn.DisplayAll()); |
先创建了一个Class(Javascript的匿名方法)拥有2个公共的(public)的字段(本篇blog会详细讲解,继续往下看)和2个public的方法,我们创建了一个Instance--Gonn,但是我可以为这个Instance动态的添加一个DisplayAll的方法,我想任何面向对象的语言是做不到这一点的,Javascript的灵活体现之一。
现在假设一个场景,如果有很多的程序员要用这段代码,由于Javascript的易变性,程序员就可以在实例化后改变Name的值,那初始化的动作就没有意义了:
1 |
var Gonn = new Man( "Gonn" , 25); |
所以我们不能让外部的人去任意的修改这个字段,在Java或C#中我们只需要个这个字段改为Private,就万事OK了,但是Javascript没有这个关键词,那我们需要这么做呢。我们可以想下在C#除了设置Private之外我们还可以怎么做?我们可以设置Setter和Getter方法。
我们来修改下上面的代码:我们称方法一:
01 |
var Person = new Interface( "Person" , [ "SetName" , "SetAge" , "GetName" , "GetAge" ]); |
02 |
var Man = function (name, age) { |
07 |
SetName: function (name) { this .Name = name; }, |
08 |
SetAge: function (age) { this .Age = age; }, |
09 |
GetName: function () { return this .Name; }, |
10 |
GetAge: function () { return this .Age; } |
12 |
var Alan = new Man( "Alan" , 25); |
13 |
Alan.Name = "Alice" ; //悲剧了,我alert的时候变成Alice了 |
14 |
Alan.SetAge(10); //悲剧,被别人把我的年龄给这么小 |
15 |
alert(Alan.GetName()); |
16 |
Alan.DisplayAll = function () { return "Name: " + this .GetName() + "; Age: " + this .GetAge() } |
17 |
alert(Alan.DisplayAll()); |
貌似样子很像C#中的Setter和Getter,但是还是可以被外部修改。但是从约束上来看,貌似比上面的code要好看些,通过方法来设置初始值。但是问题还是没有解决,我们来看看下面一种方法:闭包。解释一下,在Javascript中是通过This关键字来开发权限的(Public)。在讲闭包之前,我们需要了解下闭包的本质: 在Javascript中,只有方法是有作用域的,如果在方法中声明的变量在外部是无法访问的,那Private的概念就出来了。
01 |
var Person = new Interface( "Person" , [ "SetName" , "SetAge" , "GetName" , "GetAge" ]); |
02 |
var Man = function (newname, newage) { |
04 |
this .SetName = function (newname) { name = newname; } |
05 |
this .SetAge = function (newage) { age = newage; } |
06 |
this .GetName = function () { return name; } |
07 |
this .GetAge = function () { return age; } |
09 |
this .SetName(newname); |
11 |
var Alan = new Man( "Alan" , 25); |
12 |
Alan.name= "Alice" ; //现在name是private了,我是无法去修改的 |
现在私有的功能就实现了,我们只是用Var来代替了This而已。//我们把公共(Public)并且可以访问Private的方法称为特权方法,比如上面的this.SetName, this.SetAge.
如果我们的公共方法不涉及到访问Private的字段,那我们可以把他们放到Prototype中。//好处是多个实例的时候内存中也只有一分拷贝
1 |
Man.prototype.DisplayAll = function () { return "Name: " + this .GetName() + "; Age: " + this .GetAge() } |
哈哈~我们来看下稍微有点难度的东西:静态变量和方法。
我们都是知道静态的东西属于类(Class),我们来修改下上面的代码:
01 |
var Person = new Interface( "Person" , [ "SetName" , "SetAge" , "GetName" , "GetAge" , "GetCount" ]); |
02 |
var Man = ( function () { |
04 |
return function (newname, newage) { |
06 |
this .SetName = function (newname) { name = newname; } |
07 |
this .SetAge = function (newage) { age = newage; } |
08 |
this .GetName = function () { return name; } |
09 |
this .GetAge = function () { return age; } |
10 |
this .GetCount = function () { return count; } |
12 |
this .SetName(newname); |
16 |
Man.prototype.DisplayAll = function () { return "Name: " + this .GetName() + "; Age: " + this .GetAge() } |
17 |
var Alan1 = new Man( "Alan" , 25); |
18 |
var Alan2 = new Man( "Alan" , 25); |
19 |
alert( "There are " +Alan2.GetCount()+ " instances of Man" ); |
不管我们是通过Alan1或Alan2去GetCount,结果都一样都是2. 这里count就是一个私有的静态变量。
- 深入理解JavaScript中的属性和特性
深入理解JavaScript中的属性和特性 JavaScript中属性和特性是完全不同的两个概念,这里我将根据自己所学,来深入理解JavaScript中的属性和特性. 主要内容如下: 理解JavaSc ...
- 2018.2.2 JavaScript中的封装
JavaScript中的封装 1.封装的概念 通过将一个方法或者属性声明为私用的,可以让对象的实现细节对其他对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束,这样可以使代码 ...
- JavaScript中面向对象的三大特性(一个菜鸟的不正经日常)
经过几天的学习,把jQuery给啃会了,但是运用的还不算特别熟练,总感觉自己在JavaScript方面的基础十分欠缺,所以继续拾起JavaScript,开始更好的编程之旅~ 今天学的是JavaScri ...
- 如何在 JavaScript 中检查字符串是否包含子字符串?
如何在 JavaScript 中检查字符串是否包含子字符串? // var test4 = _.includes(string, substring); 该方法需要此文件 <script src ...
- 第一百四十三节,JavaScript,利用封装库做百度分享
JavaScript,利用封装库做百度分享 效果图 html代码 <div id="share"> <h2>分享到</h2> <ul> ...
- JavaScript中利用Ajax 实现客户端与服务器端通信(九)
一:Ajax (Asynchronous JavaScript and XML)不是一个新的技术,事实上,它是一些旧有的成熟的技术以一种全新的更加强大的方式整合在一起 Ajax的关键技术: 1.使用X ...
- 如何在JavaScript中使用高阶函数
将另一个函数作为参数的函数,或者定义一个函数作为返回值的函数,被称为高阶函数. JavaScript可以接受高阶函数.这种处理高阶函数的能力以及其他特点,使JavaScript成为非常适合函数式编程的 ...
- 如何在JavaScript中正确引用某个方法(bind方法的应用)
在JavaScript中,方法往往涉及到上下文,也就是this,因此往往不能直接引用,就拿最常见的console.log("info…")来说,避免书写冗长的console,直接用 ...
- javaScript中利用ActiveXObject来创建FileSystemObject操作文件
注:如果用javascript读本地文件,遇到安全问题. 需在浏览器中进行设置,如下: 工具—> Internet选项->安全->自定义级别->启用“没有标识为安全的A ...
随机推荐
- 深度剖析HBase负载均衡和性能指标
深度剖析HBase负载均衡和性能指标 在分布式系统中,负载均衡是一个非常重要的功能,HBase通过Region的数量实现负载均衡,即通过hbase.master.loadbalancer.class实 ...
- 嵌入式C语言查表法
转自:https://blog.csdn.net/morixinguan/article/details/51799668 作者:Engineer-Bruce_Yang 就像下面的这个表 之前写 ...
- 怎么用Python Flask模板jinja2在网页上打印显示16进制数?
问题:Python列表(或者字典等)数据本身是10进制,现在需要以16进制输出显示在网页上 解决: Python Flask框架中 模板jinja2的If 表达式和过滤器 假设我有一个字典index, ...
- Ruby字符串的一些方法
最近因为公司需求开始看ruby,先从ruby的基本数据类型开始看 看到ruby的字符串类型string,发现ruby中的字符串单双引号是不一样的,这点和Python有那么点不一样 主要是我们对字符串进 ...
- 剑指offer题目系列一
本篇介绍<剑指offer>第二版中的四个题目:找出数组中重复的数字.二维数组中的查找.替换字符串中的空格.计算斐波那契数列第n项. 这些题目并非严格按照书中的顺序展示的,而是按自己学习的顺 ...
- 如何在Moodle中显示PPT课件
Moodle中目前是不直接支持PPT的,所以需要曲线救国: 1.安装 iSpring Free 8版本,免费版,其实是一个PPT的插件,在PPT的工具栏中有显示. 2.打开PPT后,直接在该工具中进行 ...
- 【jQuery】 资料
[jQuery] 资料 1. 选择器 http://www.w3school.com.cn/jquery/jquery_ref_selectors.asp 2. 事件 http://www.w3sch ...
- 【数据库】 SQL SERVER 2014 实用新特性
[数据库] SQL SERVER 2014 实用新特性 官方链接 一. 内存优化表 大幅提高数据库性能,不过目前没有窗口化设计只能写语句 二. 索引增强
- Word 2013 无法撤销操作的错误
来自 <http://delxu.blog.51cto.com/975660/1409139> 关闭正在运行的所有程序. 按Win-R,在运行框中键入regedit,然后单击“确定”. 在 ...
- 机器学习实战一:kNN手写识别系统
实战一:kNN手写识别系统 本文将一步步地构造使用K-近邻分类器的手写识别系统.由于能力有限,这里构造的系统只能识别0-9.需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:32像素*3 ...