对于熟悉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 ...
随机推荐
- 第一次学习tornado小练习
内容 这次是python的一个web框架,tornado,这个web框架在python的几个web框架中一个比较简单的web框架,刚开始接触python的时候就知道python有两个比较常用的web框 ...
- sort函数
做项目的时候,排序是一种经常要用到的操作.如果每次都自己写个冒泡之类的O(n^2)排序,不但程序容易超时,而且浪费宝贵的时间,还很有可能写错.STL里面有个sort函数,可以直接对数组排序,复杂度为n ...
- Matplotlib 图表的样式参数
1. import numpy as np import pandas as pd import matplotlib.pyplot as plt % matplotlib inline # 导入相关 ...
- 使用 MySQL 存储 Hue 元数据
1.在 MySQL 中增加数据库 hue 2.编辑 hue.ini 文件 [[database]] # Database engine is typically one of: # postgresq ...
- CentOS7安装Oracle 11gR2 图文详解
注:Oracle11gR2 X64安装 一.环境准备 安装包: 1.VMware-workstation-full-11.1.0-2496824.exe 2.CentOS-7-x86_64-DVD-1 ...
- 《百词斩·象形9000》第一册(上) 符号Symbol 1
001-upon prep. 在......上面 Wish upon a star.#对着星星许愿. 002-think V. 想,思索,认为:以为,预料 What do you think?#你认为 ...
- Wordpress 从 MySQL 获取文章链接 permalinks
SELECT wpp.post_title, wpp.guid, wpp.post_date, REPLACE( REPLACE( REPLACE( REPLACE( wpo.option_value ...
- Laxcus大数据分布计算演示实例
Laxcus大数据管理系统提供了基于Diffuse/Converge分布算法的计算能力.算法的具体介绍详见<Laxcus:大数据处理系统>一文.本图展示了在集群环境下的随机数产生.排序.显 ...
- shell语句for循环
一:常用格式 格式一 for 变量 do 语句 done 格式二 for 变量 in 列表 do 语句 done 格式三 for ((变量=初始值; 条件判断; 变量变化)) do 语句 done 二 ...
- rcnn spp_net
在http://www.cnblogs.com/jianyingzhou/p/4086578.html中 提到 rcnn开创性工作,但是计算时间太长,重复计算太大. spp_net将重复计算避免了 我 ...