单例模式
提示:单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象
例子一
var person1 = {
name: "朱",
age: 18,
say:function(){
console.log("我是person1的say方法");
}
};
例子二
class Db {
static getInstance() {
/*1、单例 多次实例化实例不共享的问题*/
if (!Db.instance) {
Db.instance = new Db();
}
return Db.instance;
}
constructor() {
this.dbClient = ""; /*属性*/
}
}
module.exports = Db.getInstance();
构造函数模式
提示:构造函数用于创建特定类型的对象——不仅声明了使用的对象,构造函数还可以接受参数以便第一次创建对象的时候设置对象的成员值。你可以自定义自己的构造函数,然后在里面声明自定义类型对象的属性或方法
function Car(model, year, miles) {
if (!(this instanceof Car)) {
return new Car(model, year, miles);
}
this.model = model;
this.year = year;
this.miles = miles;
this.output = function () {
return this.model + "走了" + this.miles + "公里";
}
}
var tom = new Car("大叔", 2009, 20000);
var dudu = Car("Dudu", 2010, 5000);
console.log(typeof tom); // "object"
console.log(tom.output()); // "大叔走了20000公里"
console.log(typeof dudu); // "object"
console.log(dudu.output()); // "Dudu走了5000公里"
工厂模式
提示:与创建型模式类似,工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类。 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。 这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于很多设置文件等。并且,你会经常在程序里看到工厂方法,用于让子类类定义需要创建的对象类型
例子一
var Car = (function () {
var Car = function (model, year, miles) {
this.model = model;
this.year = year;
this.miles = miles;
};
return function (model, year, miles) {
return new Car(model, year, miles);
};
})();
var tom = new Car("Tom", 2009, 20000);
var dudu = new Car("Dudu", 2010, 5000);
console.log(tom) // Car { model: 'Tom', year: 2009, miles: 20000 }
console.log(dudu) // Car { model: 'Dudu', year: 2010, miles: 5000 }
例子二
function createTshirt(name, size, color){
var o = new Object();
o.name = name;
o.size = size;
o.color = color;
o.sayName = function(){
console.log("这件T恤:" + this.name + "," + this.size + "," + this.color +",自带撩妹效果!");
};
return o;
}
var tShirt1 = createTshirt("tShirt1", "xl", "红");
var tShirt2 = createTshirt("tShirt2", "xxxl", "黑");
var tShirt3 = createTshirt("tShirt3", "xxxl", "黑");
var tShirt4 = createTshirt("tShirt4", "xxxl", "黑");
console.log(tShirt1.name) // tShirt1
console.log(tShirt2.name) // tShirt2
console.log(tShirt3.name) // tShirt3
console.log(tShirt4.name) // tShirt4
构造函数模式和工厂模式的区别
- 没有显式地创建对象;
- 直接将属性和方法赋给了 this 对象;
- 没有 return 语句。
- 执行的时候,需要写new
普通函数执行 -> createJsPerson()
构造函数模式 -> new CreateJsPerson() 通过new执行后,我们的CreateJsPerson就是一个类了,而函数执行的返回值(p1)就是CreateJsPerson这个类的一个实例
- 在函数代码执行的时候
相同:都是形成一个私有的作用域,然后 形参赋值->预解释->代码从上到下执行 (类和普通函数一样,它也有普通的一面)
不同:在代码执行之前,不用自己在手动的创建obj对象了(无显示过程),浏览器会默认的创建一个对象数据类型的值(这个对象其实就是我们当前类的一个实例)
接下来代码从上到下执行,以当前的实例为执行的主体(this代表的就是当前的实例),然后分别的把属性名和属性值赋值给当前的实例
最后浏览器会默认的把创建的实例返回
- 构造函数模式的函数,推荐首字母大写;
按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。这个做法借鉴自其他 OO 语言,主要是为了区别于 ECMAScript 中的其他函数;因为构造函数本身也是函数,只不过可以用来创建对象而已。
要创建 CreateJsPerson 的新实例,必须使用 new 操作符
会经历四个步骤;
(1) 创建一个新对象;
(2) 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象);
(3) 执行构造函数中的代码(为这个新对象添加属性);
(4) 返回新对象。
原型模式
提示:原型模式是一种创建型设计模式,Prototype模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建
例子一
class Employee{
constructor(name,age){
this.name = name
this.age = age
}
say(){
console.log(this.name+"-"+this.age)
}
}
var employee1 = new Employee("kerwin",100)
console.log(employee1)
employee1.say()
建造者模式
提示:建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
例子一
class Navbar {
init() {
console.log("navbar-init")
}
getData() {
console.log("navbar-getData")
return new Promise((resolve) => {
setTimeout(() => {
resolve("navbar-1111")
}, 1000)
})
}
render() {
console.log("navbar-render")
}
}
class List {
init() {
console.log("List-init")
}
getData() {
console.log("List-getData")
return new Promise((resolve) => {
setTimeout(() => {
resolve("list-1111")
}, 1000)
})
}
render() {
console.log("List-render")
}
}
class Creator {
async startBuild(builder) {
await builder.init()
let res = await builder.getData()
console.log(res)
await builder.render()
}
}
const op = new Creator()
op.startBuild(new Navbar())
op.startBuild(new List())
装饰器模式
提示:装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装
例子一
Function.prototype.before= function(beforeFn){
var _this = this
return function(){
//先进行前置函数调用
beforeFn.apply(this,arguments)
//执行原来的函数
return _this.apply(this,arguments)
}
}
Function.prototype.after= function(afterFn){
var _this = this
return function(){
var result = _this.apply(this,arguments)
//先进行前置函数调用
afterFn.apply(this,arguments)
//执行原来的函数
return result
}
}
function log(){
console.log("上传uv,pv数据")
}
function render(){
console.log("页面处理逻辑")
}
render = render.before(log)
filmbtn.onclick = function(){
//........
render()
//........
}
function ajax(url,method,params){
console.log(url,method,params)
}
ajax1 = ajax.before((url,method,params)=>{
params.token = "aaaaaaaaaaaaaaaaa"
})
//需要穿token
ajax1("/api","post",{
name:"kerwin"
})
//不需要 ,ajax