OOP | 构造函数模式

锦绣华年

锦绣华年

2020-06-30

▲ 点击上方蓝字关注我 ▲文 / 景朝霞来源公号 / 朝霞的光影笔记ID / zhaoxiajingjing图 / 自己画

构造函数模式

单例模式、高级单例模式

优点:把描述事务的信息都放到一个命名空间中进行归类,防止全局变量污染

缺点:不能批量生产

工厂模式

优点:用函数来封装创建对象的细节,低耦合(减少一个一个创建对象的冗余代码)、高内聚(提高代码复用率)

缺点:不清楚一个对象的类型,没有解决对象识别的问题

function createPerson(name, age, sex){     let o = new Object();     o.name = name;     o.age = age;     o.sex = sex;     o.sayName = function (){         console.log(this.name);    };     return o; } let person1 = createPerson("李雷", 26, "男"); let person2 = createPerson("韩梅梅", 28, "女");

△ 工厂模式

为了解决对象识别的问题,又一个模式出现了:构造函数模式

ECMAScript中构造函数可以用来创建特定类型的对象,比如:ObjectArray这种内置构造函数。

我们也可以创建自定义的构造函数,定义自定义对象类型的属性和方法。

function Person(name, age, sex){     this.name = name;     this.age = age;     this.sex = sex;     this.sayName = function (){         console.log(this.name);    }; } let p1 = new Person("李雷", 26, "男"); let p2 = new Person("韩梅梅", 28, "女");

△ 构造函数模式

new Person()执行和普通函数执行的不同:

new操作符这种执行方式叫做构造函数执行模式,此时的Person不仅是一个函数名,还被称为;而返回的结果赋值给p1p2是一个对象,称为实例,而函数体中的this都是这个实例。

提问:什么是类?什么是实例?

△ 21.1_工厂模式VS构造函数模式

来,来,来,大家来找茬,Person() VS createPerson() 有哪些不同?

1、没有显示地创建对象

2、直接将属性和方法赋予了this对象

3、没有return语句

约定俗成的惯例:构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。所以,这里Person中的P是大写的,构造函数也是函数,只不过可以用来创建对象而已。

那么,new关键字都做了些什么呢?

1、创建了一个新对象

2、将构造函数的this指向这个新对象

3、执行构造函数中的代码

4、返回新对象

function Person(name, age){     this.name = name;     this.age = age; } let p1 = Person("李雷", 26); let p2 = new Person("韩梅梅", 28); console.log(p1, p2); let p3 = new Person("莉莉", 27);

△ 来,亮出你的答案吧~

△ 21.2_简图new操作符做了哪些事情,请自行把p3的画出来,或者把图画全了

p1的值是:undefined

p2的值是:{name:"韩梅梅",age:28}

p2p3分别保存着Person的一个不同的实例,这两个对象都有一个construcotr(构造函数)属性,该属性指向Person

 console.log(p2.constructor === Person); // true console.log(p3.constructor === Person); // true console.log(p2.constructor === p3.constructor); // ?

△ 第三个输出啥?

对象的constructor属性是用来表示对象类型的

 let arr = []; console.log(arr.constructor === Array); //=> true let obj = {}; console.log(obj.constructor === Object); //=> true let fun = function (){}; console.log(fun.constructor === Function); //=> true let reg = /^\d+$/; console.log(reg.constructor === RegExp); //=> ?

△ L8 输出啥?

检测数据类型的方法

1、typeof 不能具体区分对象,比如:typeof {} typeof [] typeof /^$/得到的结果"object"

2、constructor可以判断实例是通过谁构造出来的

3、instanceof 检测对象类型,可以通过__proto__区分实例

4、Object.prototype.toString.call()区分具体的类型,但不能区分实例

console.log(p2 instanceof Person); //=> true console.log(p2 instanceof Object); //=> true  console.log(p3 instanceof Person); //=> ? console.log(p3 instanceof Object); //=> ?

△ 输出什么?

其中,p2p3同时也是Object的实例,是因为所有对象都继承自Object

提问

console.log(typeof 12); console.log(typeof "null"); console.log(typeof true); console.log(typeof undefined); console.log(typeof null); console.log(typeof {}); console.log(typeof function (){}); console.log(typeof NaN);

△ 输出啥?

2、""空字符串、nullundefiend有啥区别?

3、 什么是类?什么是实例?

4、 构造函数和普通函数有啥不一样?

构造函数的问题

构造函数的问题:每个方法比如:sayName都要在每个实例上重新创建一遍。

function Person(name, age, sex){     this.name = name;     this.age = age;     this.sex = sex;     this.sayName = function (){         console.log(this.name);    }; } let p1 = new Person("李雷", 26, "男"); let p2 = new Person("韩梅梅", 28, "女");

△ 构造函数:每个实例都会创建一遍sayName方法

△ 21.3_简图:每次创建实例,sayName方法都会被重新创建一次

那么,如何解决呢?

- end -

提问:请实现new关键字的逻辑

▽▽▽▽▽▽ 没啥,单纯想提醒你,点下“在看”▽▽▽▽▽▽

猜您喜欢

精彩推荐

粤ICP备16095388号-1