【JavaScript】JS高级-面向对象编程
《课前补充》
一、单例设计模式 (Singleton Pattern)
1、单例模式(就是普通对象)
表现形式:
在单例模式中,person1不仅仅是对象名,它被称为“命名空间[NameSpace]”(给堆内存空间起个名字),把描述事务的属性存放到命名空间,多个命名空间是独立分开的,互不冲突。
var person1 = {name:"",
xxx:xxx
}
作用:
把描述同一件事务的属性和特征进行“分组、归类”(存储在同一堆内存空间中),因此避免了全局变量之间的冲突和污染。
单例模式命名由来:
每一个命名空间都是JS中Object这个内置基类的实例而实例之间是相互独立互不干扰的,所以称之为‘单例’:单独的实例。
2、高级单例模式(就是自执行函数返回的对象,还是一个对象)
高级单例模式:
在给命名空间赋值时,不是直接赋值一个对象,而是先自动执行一个匿名函数,形成一个私有作用域AA(不销毁内存),在AA中创建所需堆内存,并把堆内存地址赋值给命名空间。
好处:
我们完全可以在AA中创建很多内容(变量OR函数),那些需要提供给外面调取的,我们暴露到返回的对象中(模块化实现的一种思想)
//惰性函数
var nameSpace = (function(){var n=12;
function fn(){...};
...
return {newFn:fn};//newFn就是命名空间对象的属性名;
})();
3、基于单例模式实现模块化开发
模块化开发:
- 团队协作开发时,会把产品按照功能版块进行划分,每一个功能版块有专人负责;
- 把各个版块之间公用的部分进行提取封装,后期再想实现这些功能,直接调取引用即可(模块封装)。
二、工厂模式(Factory Pattern)
1、工厂模式(借助含参的函数,通过输入不同参数返回一个对应的对象,这些对象的属性名都一样,所以类似工厂流水线)
概念:
把实现相同功能的代码进行封装,实现批量生产;
(利用一个固定函数,通过改变参数,生成同类对象)
(后期想要实现这个功能,我们只需要执行函数即可)
function createPerson(name,age){var obj = {};
obj.name=name;
obj.age=age;
return obj;
}
作用:
高内聚低耦合:减少页面中冗余代码,提高代码的重复使用率。
小贴士:设计模式,就是生成普通对象{}的方式。
面向对象编程:Object Oriented Programming
一、JS是一门编程语言(具备编程思想)
1、【面向对象】
JS\JAVA(编程语言之父) \PHP\C#\Ruby\Python\C++。。。
2、【面向过程】
C语言(编程语言之母)
二、对象、类、实例
整个JS就是基于面向对象设计和开发的语言,我们学习和实战时也要按照面向对象的思想去体会和理解。
1、对象
- 万物皆对象。
2、类
- 对象的具体细分。
- 按照功能特点进行分类:大类、小类。
3、实例
- 类中具体的一个事物。
- 拿出类别中的具体一个实例进行研究,那么当前类别下的其它实例也具备这些特点和特征。
三、基于构造函数创建自定义类(constructor)
1、在普通函数执行的基础上“new xxx()”,这样就不是普通函数执行了,而是构造函数执行,当前的函数名称称之为“类名”,接收的返回结果是当前类的一个实例;
- 自己创建的类一般首字母大写;
- 这种构造函数设计模式执行,主要用于组件、类库、插件、框架等的封装,平时编写业务逻辑一般不这样处理。
构造函数模式:
function Fn(){}
Fn();//普通函数执行
var f=new Fn();//构造函数执行,Fn就是类,f是类的一个实例
2、JS创建值的两种方式:字面量方式、构造函数方式(new)
创建引用数据类型时:
- 相同点:没有本质区别,两种创建方式都是创建对象;
- 不同点:字面量方式可以直接写属性名;
var obj={};//字面量方式,JS的单例模式
var obj=new Object();//JS的构造函数模式(后端的单例模式)
//不管哪种,创造出来的都是Object类的实例,而实例之间是独立分开的,所以var xxx={}这种模式就是JS中的单例模式。
创建基本数据类型时:
- 不同点:基于字面量方式创建出来的值是基本数据类型
- 不同点:基于构造函数 (new)创建出来的值是引用类型(开堆内存)
- 相同点:没有本质不同,都是当前数据类的实例,都能使用类提供的属性和方法;
var num1=12;
var num2=new Number(12);
console.log(typeof num1);//"number"
console.log(typeof num2);//"object"
//num1、num2都是数字类的实例,只是js表达数字的方式不同,都能使用数字类提供的属性和方法。
3、构造函数执行机制
普通函数执行:
- 形成一个私有作用域;
- 形参赋值;
- 变量提升;
- 代码执行;
- 栈内存是否释放。
function Fn(){}
Fn();
构造函数执行机制:
- 形成一个私有作用域;
- 形参赋值;
- 变量提升;
- 【构造函数独有】在当前私有栈中创建一个对象(开辟一块堆内存,暂时不存储任何东西),让函数执行主体中的this指向这个堆内存;
- 代码自上而下执行;
- 【构造函数独有】代码执行完,把之前创建的堆内存地址返回。
function Fn(name,age){var n=10;
this.name=name;
this.age=age+n
}
var f= new Fn('xxx',20);
console.log(f.n);//undefined,n是私有作用域中的私有变量,不是实例的属性;
构造函数机制中细节
- 一般构造函数不写return,浏览器默认返回创建的实例堆内存地址;
- 如果构造函数中写了return:
- return返回基本值:返回的结果依然是类的实例;
- return返回引用值: 则会覆盖返回的实例;
- 所以构造函数减少使用return,一般用也是只写return:结束代码继续执行的作用,并且不会覆盖返回的实例;
- Fn;=函数本身、Fn();=普通函数执行;
- new Fn();构造函数执行创建实例、new Fn;也是构造函数执行创建实例,不能传参了。
function Fn(){var n=10;
this.m=n;
return;
}
var f=new Fn();
检测实例属于类:
1、instanceof:检测某个实例是否隶属于这个类
console.log(f instanceof Fn);//true
console.log(f instanceof Array);//false
console.log(f instanceof Object);//true,万物皆对象
console.log(1 instanceof Number);//false,所以一般用于检测引用数据类型
检测属性与对象:
1、in方法:检测当前对象是否有(能使用)某个属性(不管当前这个属性是对象的私有属性还是公有属性,都返回true)
console.log('m' in f);//true
console.log('n' in f);//false
console.log('toString' in f);//true
2、hasOwnProperty方法:检测当前对象是否存在某个私有属性
console.log(f.hasOwnProperty('m'));//true
console.log(f.hasOwnProperty('n'));//false
console.log(f.hasOwnProperty('toString'));//false
四、原型链设计模式
原型(prototype):对于函数、类而言;
原型链(_ _ proto _ _):对于对象、实例而言;
JS中引用类型分类:
- 函数类型:普通函数、所有的类(new 函数时函数就是类,内置类、自己创建的类)
- 对象类型:普通对象、数组、正则、Math、实例(除了基本类型的字面量创建的值)、函数、万物
原型链机制:
1、所有函数类型数据,都天生自带一个属性:prototype(原型),这个属性的值是一个对象(浏览器默认给它开辟一个堆内存);
prototype属性:用于当前类存储一些公共的属性和方法,供它的实例调取使用。
2、在浏览器给prototype开辟的堆内存中有一个天生自带的属性:constructor,这个属性存储的值是当前函数本身;
Array.prototype.constructor===Array;//true
3、每一个(万物)对象都有一个__proto__的属性,这个属性指向当前实例所属类的prototype。(如果不能确定它是谁的实例,都是Object类的实例)
var arr = new Array();
arr.__proto__===Array.prototype;//true,属性值是个对象
__proto__属性:用于当前实例找到所属类上公有的属性和方法;
4、基类Object的原型(prototype)对象上的__proto__指向null,因为到最底层类,如果指向也是指向自己,没有意义。
console.log(Object.prototype.__proto__);//null;
5、判断当前对象是谁的实例:看原型链(proto)上有哪个类的prototype,就是哪个类的实例;
原型链查找机制:
它是一种基于__proto__向上查找的机制。
1、当实例调用某个属性或方法时,先在自身空间找,找到则结束查找,使用私有的即可;
2、没有找到,就通过实例对象中的__proto__原型链属性,继续向上去所属类的prototype原型属性中找公共方法,找到则使用公有的;
3、再没有找到,就沿着所属类原型中的__proto__属性,一直向上找到基类Object.prototype原型对象,没有找到就不存在:undefined;
【THIS的七种情况】
1、给当前元素的某个事件绑定方法,当事件触发方法执行,方法中的this指向是当前元素本身;
2、方法执行,看前面有没有点“.”,有点,点前面是谁,this就是谁;没有点就是window对象;
3、构造函数执行的时候,方法体中的this就是当前构造函数类的实例;
4、自执行函数一般都是window对象;
5、定时器中this:window对象(通过call传入的window对象);
6、对象方法中this指向对象本身(受定时器影响:window);
7、箭头函数中this,沿作用域链向外找,直到有this定义(不受内部定时器影响)。
【JavaScript】JS高级-面向对象编程相关推荐
- 前端与移动开发----JS高级----面向对象编程,类与实例对象,继承,严格模式,模板字符串,class封装tab栏
JS高级01 回顾上阶段 Javascript组成 ECMAScript: 基础语法 (变量, 表达式, 循环, 判断, 函数, 对象等) DOM: document 操作标签(获取, 增加, 插入, ...
- JavaScript学习笔记---面向对象编程-JS高级部分(pink老师)
目录 一.面向对象编程介绍 1.1 两大编程思想 1.面向过程编程POP(Process-Oriented Programming) 2.面向对象编程OOP(Object Oriented Progr ...
- javaScript设计模式之面向对象编程(object-oriented programming,OOP)(二)
接上一篇 面向对象编程的理解? 答:面向对象编程,就是将你的需求抽象成一个对象,然后针对这个对象分析其特征(属性)与动作(方法).这个对象我们称之为类.面向对象编程思想其中一个特点就是封装,就是把你需 ...
- javascript 绘制uml_js面向对象编程和UML类图的设计
引言 前端一直以来由于JavaScript的语言特性和一些限制导致不能很好的和Java等强类型语言一样面向对象化编程,导致es6到来以后,class的语法糖或者ts中面向对象编程的设计显得比较薄弱,接 ...
- 【前端系列教程之JavaScript】15_JavaScript面向对象编程
JavaScript面向对象编程 面向对象概述 什么是对象 Everything is object (万物皆对象) 对象到底是什么,我们可以从两次层次来理解. (1) 对象是单个事物的抽象. 一本书 ...
- JS基础——面向对象编程OOP
面向对象编程有三大特点:封装.继承.多态.JS中不存在多态的概念,因此JS不是面向对象的语言,是基于对象的语言. 封装 将一个实体的信息.功能等都封装在一个对象上的特性.JS中的构造函数和类都是封装d ...
- JavaScript 数据类型、面向对象编程
目录 数据类型 变量 类型转换 字符串常用方法 数值型常用方法 数组 数组的创建.赋值 数组常用方法 数组迭代 对象 对象的创建.使用 遍历对象 操作对象属性的2种方式 快速置空对象各个字段的值 js ...
- JavaScript教程-38-JavaScript面向对象编程
1:JavaScript不是面向对象的一种编程语言,而是基于对象的.因为JavaScript是基于对象的一种脚本语言,所以没有所谓的类似java中 类 class 的概念.但是我们可以通过JavaSc ...
- js通过面向对象编程思想实现小球碰撞的小练习
一开始想着是通过构造函数来定义小球类,但是发现ES6的class关键字更高级和简便,但这只是简单的运用,如果有什么需要改进的地方或者不足,欢迎大家指出扶正. 首先,我们先定义一个父容器. <di ...
- JS高级----面向对象
面向对象 面向对象是一种编程思想. 主要是把事物给对象化,包括其属性和行为.总体来说面向对象的底层还是面向过程,面向过程抽象成类,然后封装,方便使用就是面向对象. 构造函数: 构造函数是专门用于创建对 ...
最新文章
- 阿里云云服务器Centos7部署JDK8+Nginx+Tomcat8+Mysql5.7
- VMware 虚拟化编程(15) — VMware 虚拟机的恢复方案设计
- 设计模式笔记15:代理模式(Proxy Pattern)
- range 和 xrange
- 一步步编写操作系统 71 直接操作显卡,编写自己的打印函数71-74
- 超频,如何超频CPU和显卡?
- 2013.8.4thinkPHp学习
- 【软件项目管理】软件项目的主要成本是人的劳动的消耗
- 用rsync修复不完整的Linux光盘映像文件
- 【Flex】读取本地JSON,然后JSON数据转成XML数据
- 如何使用cURL一次测量请求和响应时间?
- 接口 java性能_MyPerf4J 一个极快的Java接口性能监控和统计工具
- 学习web前端技术的笔记,仅供自己查阅备忘,移动对font-size的控制(并非原创)...
- ArrayUtils
- #C语言或C++中强大的图形库——easyx
- Multisim10.0.1汉化时没有stringfiles问题
- java.exe 0xc000012d_应用程序无法正常启动 0xc000012d
- CRM系统与呼叫中心系统对接
- 番茄花园 产业链 洪磊 中国
- 闪电Android视频转换器,闪电Android视频转换器
热门文章
- 模拟信号的调制与解调
- 图解数据分析(4) | 核心步骤1 - 业务认知与数据初探(数据科学家入门·完结)
- pixi 平铺精灵 demo (一)
- 知行:程序员如何保持二者的平衡
- HTML 实现仿 Windows 桌面主题特效
- [buuctf.reverse] 144_[XMAN2018排位赛]easyvm 147_[XNUCA2018]Code_Interpreter
- android 获取图片信息 之 ExifInterface
- win10文件夹加密_专业的文件隐藏软件——文件夹隐藏精灵PC软件
- 祝贺父亲节快乐的python代码_2019祝爸爸父亲节快乐的最新父亲节祝福说说句子大全...
- 嵌入式系统开发-麦子学院(13)-linux底层系统开发(1)