我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧!

我们都知道JavaScript是面向对象的语言,但是JavaScript是弱类型语言,没有比如C#这些强类型语言那种通过class等关键字实现类的封装方式,不过我们可以通过一些特性模仿实现类型的功能。

首先我们创建一个类

var Students=function(id,name,age){
this.id=id;
this.name=name;
this.age=age;
}

当然也可以像我们之前讲的那样通过在类的原型上添加属性和方法,比如

Students.prototype={
getStuInfo:function(){ }
};

当然这两种方法不要混合使用

这样我们就把我们需要的属性和方法都封装在我们抽象的Student类里了,当我们使用功能方法的时候我们不能直接使用这个类,需要用new关键字来实例化创建新的对象。

var student=new Students(1,'张三',20);

这样我们通过student.name的方式得到张三这个人的姓名。

或许有人会问了你通过this也可以添加属性和方法通过prototype也能添加属性和方法,那么这两者有什么区别呢?

是这样的JavaScript是一种基于原型prototype的语言所以每创建一个对象时,它都有一个原型prototype用于指向其继承的属性、方法。

那么通过prototype继承的方法并不是对象自身的所以我们每次通过类创建一个新对象时原来的这些属性和方法不会再次创建。

而通过this添加的属性、方法是在当前对象上添加的,每次创建新对象this所指向的属性和方法都会得到相应的创建。

既然我们已经能创建类,那么类里面对属性方法的隐藏和暴露我们也能通过JavaScript的函数级作用域来模仿实现

var Students=function(id,name,age)
{
//私有属性
var hobby='学习';
//私有方法
function learningMethod(){ };
//特权方法
this.getName=function(){};
this.setName=function(){};
this.getAge=function(){};
this.setAge=function(){};
//对象公有属性
this.id=id;
//对象公有方法
this.replication=function(){};
//构造器
this.setName(name);
this.setAge(age);
};

正如我上面示例中一样,声明在函数内部的变量外界是访问不到的通过这个特性我们可以创建类的私有变量以及私有方法。

而通过this创建的属性和方法,在类创建时都会相应创建,因此我们可以看成是公有属性和公有方法。

还有部分通过this创建的方法,可以访问到类或对象自身的私有属性和私有方法,我们可以看做特权方法,特权方法也可以看做是类的构造器。

那么我们在类的外部通过点语法定义的属性和方法以及在外部通过prototype定义的属性和方法又有什么作用呢?

直接通过点语法定义的属性和方法,我们在新创建的对象中无法获取他们,但是可以通过类来使用,所以我们称他们为类的静态公有属性和类的静态公有方法。

而prototye添加的属性和方法,我们在类的实例对象中可以通过this访问所以我们依然称他们为类的公有属性,和类的公有方法。

Students.primary=true;//类的静态公有属性
Students.admissionTime=function(){
console.log("2017");
};//类的静态公有方法
Students.prototype={
//公有属性
middle:false,
//公有方法
resetTime:function(){}
}

通过new关键字创建的对象的实质是对新对象this的不断赋值,并将prototype所指向类的prototype所指向的对象,听上去比较绕口,因为prototype是一级一级来查找得到的所以我们只要理解为最后会找到这个对象原型的根就行了。

所以在类的构造函数外面通过点语法定义的属性和方法是不会添加到新创建的对象上去的而通过类的原型prototype定义的对象就可以直接在新对象里使用,因为新对象的prototype和类的prototype指向的是同一个对象

我们可以测试一下,我们先实例化我们之前的Students类,然后用log打印出来看看具体显示什么

var student=new Students(1,'张三',23);
console.log(student.hobby);//undefined
console.log(student.middle);//false
console.log(student.id);//1
console.log(student.primary);//undefined

我们可以看到类的私有属性和类的静态公有属性在新创建的student对象里是访问不到的,而类的公有属性在student对象中可以通过点语法访问的到。

如同我们之前提到的类的静态公有属性和方法可以通过类的自身访问。

console.log(Students.primary);//true
Students.admissionTime();//2017

一般我们将类的静态变量通过闭包来实现

var Students=(function(){
//静态私有变量
var hobby='学习';
var studentNum=0;
//静态私有方法
function learningMethod(name){ };
//创建类
function student(newId,newName,newAge){
//私有变量
var name,age;
//私有方法
function checkId(id){};
//特权方法
this.getName=function(){};
this.setName=function(){};
this.getAge=function(){};
this.setAge=function(){};
//公有属性
this.id=newId;
//公有方法
this.replication=function(){};
if(studentNum>10)
throw new Error('我们只招收10名学生。');
//构造器
this.setName(name);
this.setAge(age);
}
//构造原型
student.prototype={
//静态公有属性
middle:false,
//静态公有方法
resetTime:function(){}
};
return student;
})();

这里我们介绍一下闭包,闭包是指有权限访问另一个函数作用域中变量的函数,即在一个函数内部创建另一个函数。

我们将这个闭包作为创建对象的构造函数,这样它既是闭包又是可实例的对象函数。

但是这样写好像还是有点美中不足,在JavaScript中并没有像C#那样的智能提示,在创建对象的时候没有使用new关键字不会给出错误提示,现在我们看如果我们创建对象不给new会怎么样。

现在我们用最开始的那个例子做示例

var Students=function(id,name,age){
this.id=id;
this.name=name;
this.age=age;
}
var student=Students(1,'张三',17);

你看我们实例化了一个叫张三的学生现在我们用log打印出来看看

console.log(student);//undefined

实际上他会显示未定义,为什么会出现这种情况呢?

我们再来打印3个属性看看

console.log(window.id);//1
console.log(window.name);//张三
console.log(window.age);//17

我们会发现我们创建了一个Students对象,但是赋值的属性添加到了window上面与,这是因为我们没用new关键字来实例化,new关键字可以看作是对当前对象的this不停的赋值。

所以,这个函数在全局中执行了,而全局作用域的this指向的当前对象就是全局变量,所以添加到Studnets的属性被添加到了window上面。

那我们如何去避免这个问题呢?

我们可以用instanceof去判断实例的是否是当前的对象如果不是,我们重新创建这个对象

var Students=function(id,name,age){
if(this instanceof Students){
this.id=id;
this.name=name;
this.age=age;
}else{
return new Students(id,name,age);
}
}
var student=Students(1,'张三',17);

我们再来看一看打印出来的东西吧

console.log(student);//Students

现在我们就能直接把对象打印出来了。

好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。

再起航,我的学习笔记之JavaScript设计模式02的更多相关文章

  1. 再起航,我的学习笔记之JavaScript设计模式01

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 在通 ...

  2. 再起航,我的学习笔记之JavaScript设计模式03

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 上一 ...

  3. 再起航,我的学习笔记之JavaScript设计模式04

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 上回 ...

  4. 再起航,我的学习笔记之JavaScript设计模式05(简单工程模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  5. 再起航,我的学习笔记之JavaScript设计模式06(工厂方法模式)

    上一次已经给大家介绍了简单工厂模式,相信大家对创建型设计模式有了初步的了解,本次我将给大家介绍的是工厂方法模式. 工厂方法模式 工厂方法模式(Factory Method):通过对产品类的抽象使其创建 ...

  6. 再起航,我的学习笔记之JavaScript设计模式05(简单工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  7. 再起航,我的学习笔记之JavaScript设计模式06(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

  8. 再起航,我的学习笔记之JavaScript设计模式08(建造者模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  9. 再起航,我的学习笔记之JavaScript设计模式09(原型模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 我们 ...

随机推荐

  1. Apache和PHP环境配置

    最近闲来想学习一下PHP. 工欲善其事,必先利其器.我的PHP环境配置了三遍,才安装成功. 下面就分享一下我的安装经验. 1.Apache2.4,PHP5.6,MySql5.6这些都是从官网下载的. ...

  2. JavaScript设计模式_10_职责链模式

    职责链模式的定义是:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止.职责链模式的名字非常形象,一系列可能 ...

  3. openfire极限优化

    日志优化   默认是 用info 级别,最好不用openfire原生的打日志方式.   离线消息用存储不打回方式,不要用打回方式   xmpp.offline.type=store_and_drop ...

  4. IT学习网站

    网站 网站定位 http://www.51cto.com/ 中国领先的IT技术网站. http://www.iteye.com/ 内容齐全,功能丰富的中文IT技术门户和社区网站. http://www ...

  5. cygwin vi编辑器左右上下键和删除键乱码错误

    安装cygwin后使用其中的vi编辑器时发现上下左右键和删除键乱码,搜索了中文的帮助方案,没有解决,最后搜索了英文的网站,找到了解决方案.参考链接如下:http://superuser.com/que ...

  6. Python: 作图

    在python中实现数据的可视化,也即作图,一般是依赖matplotlib宏包实现的.但常见的代码中都是加载pylab,是不是这里写错了呀?其实pylib只是matplotlib的一个模块,只是被做成 ...

  7. jenkins构建后操作添加“Publish to Subversion repository”与Eclipse更新提交SVN文件冲突

    jenkins配置环境信息: 1.安装“SVN Publisher plugin”插件: 2.在系统管理-系统设置中“Global SVN Publisher Settings” 填写信息:

  8. 【Android Developers Training】 64. 绘制形状

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. Java内部类与final关键字详解

    一.内部类的几种创建方法: 1.成员内部类 class Outer{ private int i = 1; class Inner{ public void fun() {System.out.pri ...

  10. 异常:java.lang.NoSuchMethodError: org.apache.poi.ss.usermodel.Workbook.getCellStyleAt

    背景 最近公司所有新项目要使用最新高效快速开发框架nature-framework,框架本身结合NatureMap已经集成excel的高效导入功能,我们要实现高性能的导出功能,因为最新的jxls-2. ...