单例设计模式(Singleton Pattern)
1. 单例模式解决的问题:
表现形式:javascript
Var obj = { xxx; xxx, … }
2. 做用:
把描述同一件事物的属性和特征进行“分组、分类”(存储在同一个推内存空间中),所以避免了全局变量之间的冲突和污染
var pattern1 = {name: ‘xxx’} var pattern2 = { name: ‘xxx’} //name值并非一个值,属于两个堆内存空间中
在单例设计模型中,obj不只仅是对象名,它被称为”命名空间[NameSpace]”,
把描述事务的属性存放到命名空间中,多个命名空间是独立分开的,互不冲突
java
3. 单例设计模式命名的由来
每个命名空间都是js中Object这个内置基类的实例,而实例之间是相互对立不干扰的,因此咱们称它为“单例”:单独的实例
编程
4. 高级单例模式
- 在给命名空间赋值的时候,不是直接赋值一个对象,而是先执行匿名函数,造成一个私有做用域AA(不销毁的栈内存),在AA中建立以爱国堆内存,把内存地址赋值给命名空间
- 这种模式的好处:咱们彻底能够在AA中创造不少内容(变量或者函数),哪些须要供外面的调取使用的,咱们暴露到返回的对象中(模块化实现的一种思想)
以下图例子:设计模式
var nameSpace = (function () { var n = 12 function fn () {} return { fn: fn } })
this:数组
- 给当前元素的某个事件绑定方法,当事件触发方法执行的时候,方法中的this是当前元素操做的元素对象
- 普通函数执行,函数中的this取决于执行的主体,谁执行的,this就是谁(执行主体:方法执行,看方法名前面是否有“点”,有的话,点前面是谁this就是谁,没有this是window)
function fn () { console.log(1) } var obj = {fn:fn} // 执行的是相同的方法,可是this指向不一样 obj.fn(); // this=> obj fn(); // this指向window // 自执行函数,方法的this指向window ~function() { // this => window } ()
var n = 2; var obj = { n: 3, fn:(function (n) { n *= 2; this.n += 2; var n = 5; return function(m) { this.n *= 2; console.log(m + (++n)) } //自执行函数执行的时候,堆内存尚未存储完成键值对,和obj尚未关系,此时obj=undefined,obj.n会报错 })(n) } var fn = obj.fn fn(3) // 9 obj.fn(3) // 10 console.log(n, obj.n) // 8 6
解析以下图:浏览器
5. 基于单例的模块化开发
工厂模式(Factory Pattern)
工厂模式(Factory Pattern)框架
- 把实现相同功能的代码进行‘封装’,以此来实现‘批量生产’(后期想要实现这个功能,咱们只需执行函数便可)
- ‘低耦合高内聚’:减小页面中的冗余代码,提升代码的重复使用率
function createPerson (name, age) { var obj = {} obj.name = name; obj.age = age; return obj } var p1 = createPerson('xxx', 25) var p2 = createPerson('xxx', 25) console.log()
拥抱面向对象
面向对象编程,咱们须要掌握“对象、类、实例”的概念
对象:万物皆对象
类: 对象的具体细分(按照功能特色进行分类:大类、小类)
实例:类中具体的一个事物(拿出类别中的具体一个实例进行研究,那么当前类别下的其余实例也具有这些特色和特征)
js中内置类
object 对象类 (基类)
模块化
-
Number数字类 String Boolean Null Undefined Array RegExp Function Date …函数
-
HTMLCollection 每个元素集合都是它的实例this
-
NodeList
-
EventTarget
Node: Element:HTMLBodyElement HTMLDivElement<br /> WindowProperties: Window: window对象就是它的实例
-
基于基类,咱们能够建立不少本身的类(自定义类)
构造函数(constructor)
1. 基于构造函数建立自定义类(constructor)
- 在普通函数执行的基础上“new xxx()”,这样就不是普通函数执行了,而是构造函数执行,当前函数名称称之“类名”,接收返回的函数结果是当前类的一个实例
- 本身建立的类名,最好第一个单词首字母大写
- 这种构造函数设计模式执行,主要用于组件、类库、插件、框架等的封装,平时编写业务逻辑通常不用这样处理
function Fn() {} var f1 = new Fn() //Fn是类 f1是类的一个实例 var f2 = new Fn() // f2也是Fn的一个实例 // f1和f2是独立的,互不影响
2. JS中建立值有两种方式:
- 字面量方式
var obj = {}
- 构造函数模式
var obj = new Object()
无论哪种方式创造出来的都是Object类的实例,而实例之间是独立分开的,因此var xxx = {} 这种模式也是js中的单例模式.
3. 基本数据类型基于两种不一样的模式建立出来的值是不同的
- 基于字面量方式建立出来的值是基本类型值
- 基于构造函数建立出来的值是引用类型
var num1 = 12; // 数字类Number实例,数字类的特殊表达方式之一 var num2 = new Number(12); // 数字类的实例 console.log(typeof num1) // "number" console.log(typeof num2) // "object"
4. 构造函数运行机制
普通函数执行:
- 造成一个私有的做用域
- 行参赋值
- 变量提高
- 代码执行
- 栈内存释放问题
普通函数执行流程以下图:
构造函数执行:
既有普通函数执行的一面,也有构造函数执行的一面
function Fn(name, age) { var n = 10; this.name = name; this.age = age + n; } var f1 = new Fn('xxx', 20); var f2 = new Fn('aaa', 30) console.log(f1=== f2); // false:两个不一样的实例(两个不一样的堆内存地址) console.log(f1.age) //30 console.log(f2.name) // 'aaa' console.log('name' in f1) // true name和age在两个不一样的实例都有存储,可是都是每一个实例本身的私有属性 console.log(f1.n) // undefined 只有this.xxx =xxx 的才和实例有关系,n是私有做用域的一个私有变量而已
- 像普通函数执行同样,造成一个私有做用域(栈内存)
行参赋值、变量提高,都是私有变量
- 【构造函数独有操做】在js代码自上而下执行以前,首先在当前造成的私有栈中建立一个对象(建立一个堆内存:暂时不存储任何东西),而且让函数中的执行主体(this)指向这个新的堆内存(this === 建立的对象)
- 代码开始自上而下执行
- 【构造函数执行独有】代码执行完成,把以前建立的堆内存地址返回(浏览器默认返回)
5. 构造函数中的一些细节问题
- 构造函数执行,不写return ,浏览器会默认返回建立的实例,若是本身写了return
- return 是一个基本值,返回的结果依然是类的实例
- 直接return是结束代码执行,不会覆盖实例
- 若是返回的是引用值,则会把默认值返回的实例覆盖,此时接收到结果就再也不是当前类的实例了
因此构造函数执行的时候,尽可能减小return使用,防止覆盖实例
**
- 在构造函数执行的时候,若是不须要传递实参数,咱们能够省略小括号,仍是建立实例(和加小括号是没有区别的)
- instanceof: 检测某一个实例是否隶属于这个类
- in:检测当前对象是否存在某个属性(无论当前这个属性是对象的私有属性仍是公有属性,只要有结果就是true)
- hasOwnProperty: 检测当前属性是否为对象的私有属性(不只要有这个属性,并且必须仍是私有的才能够)
原型链设计模式(prototype & proto)
1. 原型链机制
原型(prototype)、原型链(proto)
[函数]
普通函数、类(全部的类:内置类、本身建立的类)
[对象]
普通对象、数组、正则、Math
实例是对象类型的(除了基本类型的字面量建立的值)
prototype的值也是对象类型的
函数也是对象类型
…
- 全部的函数数据类型都是天生自带一个属性:prototype(原型),这个属性的值是一个对象,浏览器会默认给它开辟一个堆内存
- 在浏览器给prototype开辟的堆内存中,有一个天生自带的属性:constructor,这个属性存储的值是当前函数自己
- 每个对象都有一个__proto__的属性,这个属性指向当前实例所属类的prototype
原型链:
它是一种基于__proto__向上查找的机制。当咱们操做实例的某个属性或者方法的时候,首先找本身空间中私有属性或者方法
- 找到了,则结束查找,使用本身私有的便可
- 没有找到,则基于__proto__找所属类的prototype,若是没找到,基于原型上的__proto__继续,向上查找,一直找到Object.prototype的原型为止,若是再没有,操做的属性或者方法不存在
function Fn() { var n = 10; this.AA = function () { console.log('AA') } this.BB = function () { console.log('BB') } } Fn.prototype.AA = function () { console.log('AA[公]') }; var f1 = new Fn; var f2 = new Fn
解析以下图:
总结:
本篇文章主要分享了面向对象的一些知识,若是想了解更多,请扫下面二维码,关注公众号