夯实基础,彻底掌握js的核心技术(二):面向对象编程(Object Oriented Programming)

单例设计模式(Singleton Pattern)

1. 单例模式解决的问题:

表现形式:

Var obj = {
xxx; xxx,
…
}

2. 作用:

把描述同一件事物的属性和特征进行“分组、分类”(存储在同一个推内存空间中),因此避免了全局变量之间的冲突和污染

var pattern1 = {name: ‘xxx’}
var pattern2 = { name: ‘xxx’}
//name值并不是一个值,属于两个堆内存空间中

在单例设计模型中,obj不仅仅是对象名,它被称为”命名空间[NameSpace]”,<br />把描述事务的属性存放到命名空间中,多个命名空间是独立分开的,互不冲突

3. 单例设计模式命名的由来

每一个命名空间都是js中Object这个内置基类的实例,而实例之间是相互对立不干扰的,所以我们称它为“单例”:单独的实例

4. 高级单例模式

  1. 在给命名空间赋值的时候,不是直接赋值一个对象,而是先执行匿名函数,形成一个私有作用域AA(不销毁的栈内存),在AA中创建以爱国堆内存,把内存地址赋值给命名空间
  2. 这种模式的好处:我们完全可以在AA中创造很多内容(变量或者函数),哪些需要供外面的调取使用的,我们暴露到返回的对象中(模块化实现的一种思想)

如下图例子:

var nameSpace = (function () {
    var n = 12
    function fn () {}
    return {
    fn: fn
    }
})

this:

  1. 给当前元素的某个事件绑定方法,当事件触发方法执行的时候,方法中的this是当前元素操作的元素对象
  2. 普通函数执行,函数中的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

解析如下图:<br />
image.png
image.png

<br />
image.png
image.png

5. 基于单例的模块化开发

  1. 团队协助开发的时候,会把产品按照功能板块进行划分,每个功能板块都有专人负责开发
  2. 把各个版块之间公用的部分进行提取封装,后期在想实现这些功能,直接的调取即可

工厂模式(Factory Pattern)

工厂模式(Factory Pattern)

  1. 把实现相同功能的代码进行‘封装’,以此来实现‘批量生产’(后期想要实现这个功能,我们只需执行函数即可)
  2. ‘低耦合高内聚’:减少页面中的冗余代码,提高代码的重复使用率
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()

拥抱面向对象

面向对象编程,我们需要掌握“对象、类、实例”的概念<br />对象:万物皆对象<br />类: 对象的具体细分(按照功能特点进行分类:大类、小类)<br />实例:类中具体的一个事物(拿出类别中的具体一个实例进行研究,那么当前类别下的其他实例也具备这些特点和特征)<br />js中内置类<br />object 对象类 (基类)

  1. Number数字类 String Boolean Null Undefined Array RegExp Function Date ...

  2. HTMLCollection 每一个元素集合都是它的实例

  3. NodeList

  4. EventTarget

    Node: Element:HTMLBodyElement HTMLDivElement<br />       WindowProperties: Window: window对象就是它的实例
    
  5. 基于基类,我们可以创建很多自己的类(自定义类)

结构如下图:<br />
image.png
image.png

构造函数(constructor)

1. 基于构造函数创建自定义类(constructor)

  1. 在普通函数执行的基础上“new xxx()”,这样就不是普通函数执行了,而是构造函数执行,当前函数名称称之“类名”,接收返回的函数结果是当前类的一个实例
  2. 自己创建的类名,最好第一个单词首字母大写
  3. 这种构造函数设计模式执行,主要用于组件、类库、插件、框架等的封装,平时编写业务逻辑一般不用这样处理
function Fn() {}
var f1 = new Fn()  //Fn是类 f1是类的一个实例
var f2 = new Fn()   // f2也是Fn的一个实例
// f1和f2是独立的,互不影响

2. JS中创建值有两种方式:

  1. 字面量方式
var obj = {}
  1. 构造函数模式
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. 构造函数运行机制

<br />普通函数执行:

  1. 形成一个私有的作用域
  2. 行参赋值
  3. 变量提升
  4. 代码执行
  5. 栈内存释放问题

普通函数执行流程如下图:<br />
image.png
image.png

<br />
<br />构造函数执行:<br />既有普通函数执行的一面,也有构造函数执行的一面

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是私有作用域的一个私有变量而已

  1. 像普通函数执行一样,形成一个私有作用域(栈内存)

行参赋值、变量提升,都是私有变量

  1. 【构造函数独有操作】在js代码自上而下执行之前,首先在当前形成的私有栈中创建一个对象(创建一个堆内存:暂时不存储任何东西),并且让函数中的执行主体(this)指向这个新的堆内存(this === 创建的对象)
  2. 代码开始自上而下执行
  3. 【构造函数执行独有】代码执行完成,把之前创建的堆内存地址返回(浏览器默认返回)
image.png
image.png

<br />
image.png
image.png

5. 构造函数中的一些细节问题

  1. 构造函数执行,不写return ,浏览器会默认返回创建的实例,如果自己写了return
  • return 是一个基本值,返回的结果依然是类的实例
  • 直接return是结束代码执行,不会覆盖实例
  • 如果返回的是引用值,则会把默认值返回的实例覆盖,此时接收到结果就不再是当前类的实例了

所以构造函数执行的时候,尽量减少return使用,防止覆盖实例<br />**

  1. 在构造函数执行的时候,如果不需要传递实参数,我们可以省略小括号,还是创建实例(和加小括号是没有区别的)
  2. instanceof: 检测某一个实例是否隶属于这个类
  3. in:检测当前对象是否存在某个属性(不管当前这个属性是对象的私有属性还是公有属性,只要有结果就是true)
  4. hasOwnProperty: 检测当前属性是否为对象的私有属性(不仅要有这个属性,而且必须还是私有的才可以)

原型链设计模式(prototype & proto

1. 原型链机制

原型(prototype)、原型链(proto)<br />[函数]<br />普通函数、类(所有的类:内置类、自己创建的类)<br />[对象]<br />普通对象、数组、正则、Math<br />实例是对象类型的(除了基本类型的字面量创建的值)<br />prototype的值也是对象类型的<br />函数也是对象类型<br />...

  1. 所有的函数数据类型都是天生自带一个属性:prototype(原型),这个属性的值是一个对象,浏览器会默认给它开辟一个堆内存
  2. 在浏览器给prototype开辟的堆内存中,有一个天生自带的属性:constructor,这个属性存储的值是当前函数本身
  3. 每一个对象都有一个proto的属性,这个属性指向当前实例所属类的prototype

image.png
image.png
<br />原型链:<br />它是一种基于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

解析如下图:<br />
image.png
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容