js中的面向对象入门

http://www.cnblogs.com/chenmeng0818/p/6508755.html

什么是对象

我们先来看高程三中是如何对对象进行定义的

"无序属性的集合,其属性可以包括基本值、对象或者函数",对象是一组没有特定顺序的的值。对象的没个属性或方法都有一个俄名字,每个名字都映射到一个值。

简单来理解对象就是由属性和方法来组成的

面向对象的特点

-封装

对于一些功能相同或者相似的代码,我们可以放到一个函数中去,多次用到此功能时,我们只需要调用即可,无需多次重写。

在这里我们可以理解为创造对象的几种模式:单例模式,工厂模式,构造函数模式,原型模式等。

  • 继承

    子类可以继承父类的属性和方法

  • 多态(重载和重写)
    1. 重载:严格意义上说js中没有重载的功能,不过我们可以通过判断函数的参数的不同来实现不同的功能来模拟重载。
    2. 重写:子类可以改写父类的属性和方法

javascript中的封装

  • 单例模式
    小王在一个小公司,就自己一个前端,所以他写js都是这样的
var a = 1;
function getNum(){ return 1; }

后来公司又招了个前端小明,于是变成他们2个一起写同一个js了。一天小王发现自己写的getNum方法出问题了,原来是小华写的js中也有个getNum的函数,代码合并后把他的覆盖掉了,于是便找小华理论去,经过一番妥协后,两人都把自己的代码改了改

var xiaoming = {num:1,getNum:function(){ return 1; } } var xiaohua = { num:2, getNum: function(){ return 2; } }

这就是我们所谓的单例模式(命名空间)

我们把描述同一个事物的方法或者属性放到同一个对象里,不同事物之间的方法或者属性名相同相互也不会发生冲突。

单例模式的优劣

  1. 使用单例模式,我们可以实现简单的模块化开发

    var utils = {
    getCss:function(){//code }, getByClass:function(){ //code }, setCss:function(){ //code } }
    我们可以把自己写好的工具方法放到一个单独的js文件中,然后直接引入即可。
  2. 避免了全局变量名的冲突
    需要注意的是,我们在引入各个模块的时候,需要注意引入的顺序,引入顺序是按照各模块之间的相互依赖进行前后排列的;
  3. 缺点:
  • 单例模式只是一定程度上避免了变量名的冲突,但并不能彻底解决此问题,而且在不同的对象下,我们可能会有很多功能相同的代码,最终造成大量的冗余代码。
  • 单例模式让每个对象有了自己独立的命名空间,但是并不能批量生产的问题,每一个新的对象都要重新写一份一模一样的代码。
var person1 = {name:'小明',age:24,showName:function(){ console.log('我的名字是:'+this.name) } }; var person1 = { name:'小华', age:25, showName:function(){ console.log('我的名字是:'+this.name) } };
  • 工厂模式
  1. 工厂模式其实就是把需要一个个的编写的对象,放在一个函数中统一的进行创建,说白了就是普通函数的封装。
  2. 工厂模式总共3步骤:
    1)引进原材料 --- 创建一个空对象
    2)加工原材料 --- 加工对象:给对象添加属性和方法;
    3)输出产品 --- 返回对象:return 对象;
function CreatePerson(name,age){var obj={};//1.创建一个空对象 //2.加工对象 obj.name=name; obj.age=age; obj.showName=function(){ console.log('我的名字是:'+this.name) }; return obj;//3.输出对象; } var person1 = CreatePerson('小明',23) var person2 = CreatePerson('小华',23) person1.showName(); //我的名字是:小明 person2.showName(); //我的名字是:小华
  • 工厂模式的优缺点
    1. 既然叫工厂模式,它就和我们周围的工厂一样,我们只需要把原材料放进去,就能得到我们需要的产品了。
    2. 工厂模式也解决了单例模式的批量生产的问题,避免了单例模式中的大量冗余代码,进行系统的封装,提高代码的重复利用率
    3. 不过工厂模式跟我们js内置类的调用方法不同
  • 构造函数模式
    1. 可以创建一个自定义的类,并且可以new出实例
    2. 构造函数做的就是类和实例打交道。
    //构造函数:首字母大写(约定俗成);function CreatePerson(name,age){ //创建一个自定义的类 //构造函数中的this,都是new出来的实例 //构造函数中存放的都是私有的属性和方法; this.name=name; this.age=age; this.showName=function(){ console.log('我的名字是:'+this.name) } } //实例1 var person1 = new CreatePerson('小明',25) //实例2 var person2 = new CreatePerson('小华',24)

这里说一下工厂模式和构造函数模式的区别:

1. 在调用的时候不同:
工厂模式:调用的时候,只是普通函数的调用createPerson();
构造函数模式:new CreatePerson();
2. 在函数体内不同:
工厂模式有三步:1)创建对象 2)加工对象 3)返回对象;
构造函数模式只有1步: 只有加工对象; 因为系统默认会为其创建对象和返回对象;
3. 构造函数默认给我们返回了一个对象,如果我们非要自己手动返回的话:
    (1)手动返回的是字符串类型:对以前实例上的属性和方法没有影响;
 (2)手动返回的是引用数据类型:以前实例身上的属性和方法就被覆盖了;实例无法调用属性和方法;

构造函数的方法都是私有方法,每个实例调用的都是自己私有的方法,同样也会有许多重复的代码。

我们可以使用原型模式来解决每个实例中都有相同方法的函数的问题

  • 原型模式
    function CreatePerson(name,age){ this.name=name; this.age=age; } // 我们把公有的方法放到函数的原型链上 CreatePerson.prototype.showName = function(){ console.log('我的名字是:'+this.name) } var person1 = new CreatePerson('小明',25) var person2 = new CreatePerson('小华',24) person1.showName() //小明

###### 原型模式的关键:

1)每个函数数据类型(普通函数,类)上,都有一个属性,叫prototype。
2)prototype这个对象上,天生自带一个属性,叫constructor:指向当前这个类;
3)每个对象数据类型(普通对象,prototype,实例)上都有一个属性, 叫做__proto__:指向当前实例所属类的原型;

这3句话理解了,下边的东西就可以不用看了 //手动滑稽

通过例子我们来看这几句话是什么意思

 function CreatePerson(name,age){this.name=name; this.age=age } CreatePerson.prototype.showName=function(){ console.log('我的名字是:'+this.name) } var person1 = new CreatePerson('小明',25); console.dir(person1)

在chrome浏览器控制台中显示

从图中可以看出,person1这个对象上有name和age两个属性,
person1的__proto__指向了它的构造函数(CreatePerson)的prototype上,
而且还有一个showName的方法。
并且它们中有一条链关联着: person1.__proto__ === CreatePerson.prototype

接着来看

function Foo(){this.a=1; } Foo.prototype.a=2; Foo.prototype.b=3; var f1 = new Foo; //没有参数的话括号可以省略 console.log(f1.a) //1 console.log(f1.b) // 3 以这个为例, 当我们查找f1.a时,因为f1中有这个属性,所以我们得出 f1.a=1; 当我们查找f1.b时,f1中没有这个属性,我们便顺着f1.__proto__这条链去 它的构造器的prototype上找,所以我们得出了 f1.b = 3;

接着来说,Foo.prototype是个对象,那么它的__proto__指向哪里呢
还记的刚刚说的那句
每个对象数据类型(普通对象,prototype,实例)上都有一个属性,叫做__proto__:指向当前实例所属类的原型
此外,我们应该知道
每一个对象都是function Object这个构造函数的实例

所以我们可以接着还原这个原型图

等等,图上貌似多了个个Object.prototype.__proto__ 指向了null,这是什么鬼?

我们这么来理解,Object.prototype是个对象,
那么它的__proto__指向了它的构造函数的prototype上,
最后发现了还是指向它自身,这样转了个圈貌似是无意义的,于是便指向了null

还没完,我们发现对象都是函数(构造器)创造出来的,那么函数是谁创造的呢?石头里蹦出来的么?
在js中,function都是由function Function这个构造器创造的,每一个函数都是Function的实例

现在基本上我们就能得出了完整的原型图了

是不是有点乱?根据我们刚刚讲的是能把这个图理顺的,
这里需要注意下,Function.__proto__是指向它的prototype的

多说一点,判断数据类型的方法时,我们知道有个instanceof的方法
比如

A instanceof B

instanceof判断的规则就是:

沿着A的__proto__这条线查找的同时沿着B的prototype这条线来找,如果两条线能找到同一个引用(对象),那么就返回true。如果找到终点还未重合,则返回false。

再来看我们之前的那个例子

function Foo(){this.a=1; } Foo.prototype.a=2; Foo.prototype.b=3; var f1 = new Foo; //没有参数的话括号可以省略 console.log(f1.a) //1 console.log(f1.b) // 3 当我们查找f1.a时,因为f1中有这个属性,所以我们得出 f1.a=1; 当我们查找f1.b时,f1中没有这个属性,我们便顺着f1.__proto__这条链去它的构造器的prototype上找,所以我们得出了 f1.b = 3;

当我们查找一个对象的属性时,先在这个对象的私有空间内查找,如果没找到,就顺着对象的__proto__这条链去它的构造器的ptototype上查找,如果还没找到,接着沿__proto__向上查找,直到找到Object.prototype还没有的话,这个值就为undefined,这就是所谓的原型链

列举下网页中的一些相关的原型链

有兴趣的同学可自行通过浏览器控制台看看我们常用的方法都是在哪个类上定义的,比如getElementsByTagName,addEventListener等等

继承

在这里就主要说一下组合继承(call + 原型链)

function Father(){this.xxx= 80; this.yyy= 100; this.drink = function(){} } Father.prototype.zzz= function(){} var father = new Father; function Son(){ this.aaa = 120; this.singing = function(){} Father.call(this); } Son.prototype = new Father; Son.prototype.constructor = Son; var son = new Son console.dir(son)

这么写有个不好的地方就是:子类私有的属性中有父类私有的属性,子类公有的属性中也有父类私有的属性;
根据我们前边的知识,我们可以这么来改写

function Father(){this.xxx= 80; this.yyy= 100; this.drink = function(){} } Father.prototype.zzz= function(){} var father = new Father; function Son(){ this.aaa = 120; this.singing = function(){} Father.call(this); //利用call继承了父类的私有属性 } Son.prototype.__proto__ = Father.prototype var son = new Son console.dir(son)

最后来一张思维导图

图片如果放大也看不清的话 下载地址

转载于:https://www.cnblogs.com/libin-1/p/6509438.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356063.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

maven 父maven_Maven不会吮吸。 。 。 但是Maven文件会

maven 父maven我不会参加整个Maven辩论,但可以说我是所有最佳实践的坚定支持者,对我而言,Maven是最佳实践的体现。 我的意思是说,Maven是围绕特定的最佳实践构建方法构建的。 注意,我说了一种特定的最佳实践构建方法。…

java maven部署_eclipse中maven项目部署到tomcat

下面就一一介绍这几种部署方式:1.打war包到tomcat/webapps目录这种方式其实跟非maven项目没什么区别,就是打包的方式不同之后在target目录下会生成war包,复制到tomcat/webapps目录即完成部署。2.使用tomcat-maven插件,在pom.xml的…

word 论文排版 —— 按指定格式章节的自动编号

在word中如何实现章节标题自动编号 标题样式与标题的编号是两个步骤,为标题建立编号是在为标题样式确定的基础后进行的。这是显而易见的,也即只有先定义了多级标题(也可使用 word 自带的标题样式),才可为这些多级标题自…

vb 获取mysql表第一行数据_vb如何将远程获取的数据插入本机数据表中

双击按钮添加如下代码Private Sub Command1_Click()Dim objRemoteConn As New ADODB.ConnectionDim objLocalConn As New ADODB.ConnectionDim objRs As ADODB.RecordsetDim strSql As StringobjRemoteConn.Open "providerSQLOLE…

ASP渲染下拉框使时间依次减少

<% xyear(now()) yyear(now())-1 Do While y>2002%><li><a href"#2015" class"treeview-time"><%y%></a></li><% yy-1 loop%>转载于:https://www.cnblogs.com/mazey/p/6512893.html

Spring Cloud对Hystrix的支持

Spring Cloud项目为Netflix OSS Hystrix库提供了全面的支持。 之前我已经写过有关如何使用原始Hystrix库包装远程调用的文章。 在这里&#xff0c;我将探讨如何将Hystrix与Spring Cloud结合使用 基本 实际上并没有什么大不了的&#xff0c;这些概念仅在特定于Spring引导的增强…

OA系统部署短信过程

安装dotNetFx40_Client_setup.exe插件 安装mysql_installer_community_V5.6.21.1_setup.1415604646.msi数据库 根据数据库版本安装相应驱动&#xff08;64位或者32位系统&#xff09; 安装mysql-connector-odbc-5.3.7-winx64.msi驱动&#xff08;ODBC&#xff09;工具 安装mysq…

centos6配置mysql5.7_CentOS 6/7 下 MySQL 5.7 安装部署与配置

一、前言1、本教程主要内容MySQL 5.7安装(yum)MySQL 5.7 ROOT账号密码修改MySQL 5.7基础使用与配置MySQL shell管理常用语法示例(用户、权限等)MySQL字符编码配置2、本教程环境信息与适用范围环境信息软件版本CentOS7.4 ReleaseMySQL5.7适用范围软件版本CentOSCentOS 6 & C…

hadoop伪分布式搭建 java_hadoop2.2.0伪分布式搭建

第一步&#xff1a;安装jdk我的linux版本是centos7&#xff0c;使用最简单的安装方式&#xff0c;这里首先说一下&#xff0c;由于系统会预装openjdk版本等其他各种版本&#xff0c;首先要做的是清除这些版本&#xff0c;然后iu安装oracle的jdk版本1.1 查看所有jdk版本并删除其…

北斗有 35 颗卫星,而 GPS 有 24 颗卫星,为什么二者数量不同?

作者&#xff1a;知乎用户链接&#xff1a;https://www.zhihu.com/question/21092045/answer/17164418来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。反对目前的两个不靠谱回答&#xff01;需要的卫星数目和别人占坑没有…

可行的DeltaSpike教程

在一个最近的项目中&#xff0c;我遇到了一个有趣的问题&#xff1a;采用被赋予单个对象的服务方法&#xff0c;并在一个夜间过程的上下文中重用相同的代码&#xff0c;该过程独立于应用程序而在数千个相同类型的对象上运行。 试图在两个地方维护如此大小和复杂性的相同过程真…

2017/3/8 函数指针/事件/委托....

函数指针&#xff1a; 定义&#xff1a;函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量&#xff0c;只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样&#xff0c;这里是指向函数。 函数指针有两个用途&#xff1a;调用函数…

java finalize 析构_close,析构函数和finalize:Java矛盾

try { FileInputStream in new FileInputStream(filename);BufferedReader readernew BufferedReader(new InputStreamReader(in));String line;while((linereader.readLine())!null){// read the file}}catch (Exception e) {System.out.println(e);}但是如果我尝试将命令添加…

sharesdk短信验证码的集成

在ShareSDK官网http://mob.com/注册并创建Android应用.申请APP_key,下载SDK等 根据官网开发文档导入SDK,目录结构如下 将以上文件按需放入Android Studio项目所要使用SMSSDK的Module所在的Libs里面&#xff0c;再在Module的build.gradle里面将libs加入仓库&#xff08;reposito…

java四神兽_SpringCloud五大神兽之Eureka

注册中心概述什么是注册中心&#xff1f;相当于服务之间的‘通讯录’&#xff0c;记录了服务和服务地址之间的映射关系。在分布式架构中服务会注册到这里。当服务需要调用其他服务时&#xff0c;就在注册中心找到其他服务的地址&#xff0c;进行调用注册中心的主要作用&#xf…

Mockito入门

本文是我们名为“ 用Mockito进行测试 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入了解Mockito的魔力。 您将了解有关“模拟”&#xff0c;“间谍”和“部分模拟”的信息&#xff0c;以及它们相应的Stubbing行为。 您还将看到使用测试双打和对象匹配器进行验证的过…

windows下dubbo-admin和zookeeper安装部署

1. 概述 ZooKeeper是Hadoop的正式子项目&#xff0c;它是一个针对大型分布式系统的可靠协调系统&#xff0c;提供的功能包括&#xff1a;配置维护、名字服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务&#xff0c;将简单易用的接口和性能高效、…

jpush java api_JPush極光推送Java服務器端API

產品功能說明極光推送(JPush)是一個端到端的推送服務&#xff0c;使得服務器端消息能夠及時地推送到終端用戶手機上&#xff0c;讓開發者積極地保持與用戶的連接&#xff0c;從而提高用戶活躍度、提高應用的留存率。極光推送客戶端支持 Android, iOS 兩個平台。本 Android SDK …

Maven详解(转)

转自 https://www.cnblogs.com/hongwz/p/5456578.html 一.前言 以前做过的项目中&#xff0c;没有真正的使用过Maven&#xff0c;只知道其名声很大&#xff0c;其作用是用来管理jar 包的。最近一段时间在项目过程中使用Maven&#xff0c;用Maven构建的web项目&#xff0c;其项目…

javafx性能_对JavaFX Mobile应用程序进行性能分析

javafx性能注意&#xff1a;本文最初发表于2009年&#xff0c;仅供参考。 请查阅我们其余的JavaFX文章 。 对于每个JavaFX Mobile应用程序开发人员而言&#xff0c;今天都是美好的一天。 你想知道为什么吗&#xff1f; 因为JavaME SDK 3.0已发布。 根据我午休时听到的消息&…