对于熟悉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 ...
随机推荐
- elasticsearch 5.x 系列之四(索引模板的使用,详细得不要不要的)
1,首先看一下下面这个索引模板 curl -XPUT "master:9200/_template/template_1?pretty" -H 'Content-Type: app ...
- (杭电 1097)A hard puzzle
A hard puzzle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- Hadoop启动后无法启动NodeManager
在配置完Hadoop集群后,使用命令:“start-all.sh”进行启动集群.然后使用命令:“jps”查看进程启动情况,发现没有NodeManager 只需要使用命令:cd /usr/local/ ...
- 【jQuery】 Ajax
[jQuery] Ajax $.ajax({ type: "Post", // 发包方式 cache: false, // 是否缓存 contentType: "appl ...
- 子串查询(二维前缀数组) 2018"百度之星"程序设计大赛 - 资格赛
子串查询 Time Limit: 3500/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Subm ...
- SVN脱离锁定的几种方法
SVN经常出现被锁定而无法提交的问题,选择解锁又提示没有文件被锁定,很是头疼.这里整理了一下SVN 被锁定的几种解决方法: 1.出现这个问题后使用“清理”即"Clean up"功能 ...
- SQL - SELECT COUNT用法
SQL Server数据库 COUNT() 函数返回匹配指定条件的行数. 语法 SQL COUNT(column_name) 语法 COUNT(column_name) 函数返回指定列 ...
- virtualBox 安装 CentOs 6.8 以及网络配置
安装 virtual box 基本设置: 1.创建虚拟电脑 类型:Linux 版本:Red Hat(64-bit) 这个64/32 和电脑具体配置关系. 然后就是路next or 设置常规的东西. 2 ...
- Python全栈 MongoDB 数据库(概念、安装、创建数据)
什么是关系型数据库? 是建立在关系数据库模型基础上的数据库,借助于集合代数等概念和方法来处理数据库中的数据, 同时也是一个被组织成一组拥有正式描述性的表格( ...
- iOS-初识swift
在学习iOS开发之前,先掌握一点swift知识是必要的.note:不论是iOS开发还是编程语言的学习,都应该是迭代.由浅入深的过程,是理论实践相结合的过程. 中文文档 swift3(与swift4稍有 ...