JavaScripe的四种设计模式

发布于:2022-12-24 ⋅ 阅读:(349) ⋅ 点赞:(0)

一、分别是哪四种模式?

  1. 工厂模式
  2. 构造函数模式
  3. 原型模式
  4. 组合模式

二、知识前提

1、什么是工厂模式?

工厂模式是一种创建型模式,简单来说,工厂模式就是创建对象的一种方式

2、工厂模式有什么用?

作用:创建对象;降低代码冗余度。

类似我们使用函数的原理,传递不同的参数,就会调用同一函数,产生不同的值

应用场景:当你想要批量生产同种类的对象的时候;比如,你想生成一个班级的40个学生,每个学生都有姓名、年龄等特征。这时候你创建一个“工厂”,把信息丢到工厂里,工厂就给你造一个人出来,非常方便。

3、其它几个模式有什么用?

其它模式都是为了更快、简单的创建对象而研发出的设计模式,类似于一种历史的发展趋势、组合模式则是历史发展的最终产物,完美的解决了其它模式遇到的问题

三、详情

一、工厂模式

例子:

function createPerson(name, age) {
  // Object构造函数
  var person = new Object()
  person.name = name
  person.age = age
  // 函数是引用数据类型,所以每个实例调研时,都会重新占据一个堆区
  person.sayName = function () {
    console.log(this.name);
  }
  return person
}
var obj1 = createPerson('zhangsan', 17)
var obj2 = createPerson('lisi', 18)
console.log(obj1, obj2);
console.log(obj1 === obj2); //false

/*
优点:只要我们往工厂函数里面塞参数,工厂函数就会像生产产品一样造个人出来。
缺点:类型模糊 是大的Object 不知道是具体的哪个对象
*/

优点:只要我们往工厂函数里面塞参数,工厂函数就会像生产产品一样造个人出来

缺点:类型模糊  不知道是哪个具体对象

解决办法:使用自定义构造函数

二、自定义构造函数模式

例子:

function Person(name, age, gender) {
  this.name = name
  this.age = age
  this.gender = gender
  this.sayName = function () {
    console.log(this.name);
  }
}
// 1、new-说明Person当作一个自定义构造函数  this存在于Person中,被p1调用,所有this指向p1 同理p2
var p1 = new Person('zhangsan', 18, 'male')
var p2 = new Person('lisi', 16, 'female')
console.log(p1); //p1对象
console.log(p2);  //p2对象

 执行结果:

优点:批量创建对象 解决了工厂模式的对象类型模糊问题

缺点:方法冗余-不同的实例调用时,每实例对象中的方法会分别占据堆内存

产生缺点的原因:

解决办法:将对象中的方法写在全局

额外知识:

  • 自定义构造函数模式和工厂模式最大的区别?
    • 没有显式地创建对象。
    • 属性和方法直接赋值给了 this。
    • 没有 return。
  • instanceof——判断一个对象是某个对象的实例

将对象中的方法写在全局

例子:

// 修改后
function Person(name, age, gender) {
  this.name = name
  this.age = age
  this.gender = gender
  // 通过赋值调用即可sayName函数
  this.sayName = sayName
}
/*
放在全局,全局也会影响作用域,类似Animal构造函数也可以使用sayName(),
但我们本意是 只有Person构造函数才可以调用
*/
function sayName() {
  console.log(this.name);
}
var person1 = new Person("zhangsan", 29, "male");
var person2 = new Person("lisi", 27, "female");
person1.sayName(); // zhangsan 
person2.sayName(); // lisi
console.log(person1.sayName === person2.sayName); //true

优点:解决了在自定义函数中,每次调用都产生不同的function实例

缺点:方法冗余、影响全局作用域

解决办法:使用原型模式

三、原型模式

例子:

 解决影响全局作用域的原理:

  • 因为每个构造函数都会创建一个prototype属性(原型属性)具体可以参考对象中的原型解释。因此在构造函数给实例对象赋值,也可以给他们的原型赋值

  • 不同的实例对象,会继承对应原型对象中的方法。因此解决了 全局作用域的问题

优点:解决了代码冗余(一个实例一个方法)、影响全局作用域

额外知识:

  • 如何改变实例对象的值,而不继承?

  • 如何判断该属性是自己的属性(继承也返回false)

  •  如何判断一个属性是否属于 原型属性

 

 三、更简单的原型模式

例子:

 

优点:页面看起来更整洁

缺点1:从constructor指向发生改变

解决方式:使用defineProperty修改指向

缺点2:当实例对象p1修改了某个值,实例p2也获得了修改后的值

例子:

四、组合模式

由以上可以看出来,构造函数模式更利于存储私有属性,原型模式更利于存储共享属性

例子:

优点:解决了以上代码冗余、原型模式的问题

 


网站公告

今日签到

点亮在社区的每一天
去签到