JS中的单例模式/工厂模式/构造函数模式(并非完全意义上的设计模式)

·  阅读 74
JS中的单例模式/工厂模式/构造函数模式(并非完全意义上的设计模式)

JS中的单例模式/工厂模式/构造函数模式(并非完全意义上的设计模式) 单例模式 单例模式: 是一种项目开发中经常使用的模式,因为项目中我们可以使用单例模式来进行我们的"模块开发"

"模块化开发": 对于一个相对来说比较大的项目,需要多人协作的开发,我们一般情况下会根据当前项目的需求划分为几个功能板块,每个人负责一部分,同时开发,最后把每个人的代码进行合并

比如:

公共模块 var utils = { select: function(){

}
复制代码

} 页卡模块中的change->实现选项卡切换 var tabRender = { change: function(){ utils.select(); // 在自己的名命空间下调用其他名命空间的方法 } } +搜索模块change->搜索内容变化处理的

var searchRender = { change: function (){ this..clickEven(); // 在自己的名命空间下调用自己名命空间的方法 } clickEvent: function(){

}
复制代码

} 工厂模式 单例模式虽然解决了分组的作用,但是不能实现批量的生产,属于手工作业模式 函数的封装: 把实现同一件事情的相同的代码放到一个函数中,以后如果在想实现这个功能,不需要从新的编写这些代码了,只需要执行当前的函数即可 低耦合高内聚: 减少页面中冗余代码,提高代码的重复利用率

function createJsPerson(name, age){ var obj = {}; obj.name = name; obj.age = age; obj.writeJS = function(){ console.log("my name is " + this.name + ", i can write js ~~") } return obj; }

var p1 = createJsPerson("lemon1", 21) var p2 = createJsPerson("lemon2", 22) js中不存在重载,方法名一样的话,后面的会把前面的覆盖掉,最后只保留一个

function sum(num){ if(typeof num === "undefined"){ return 0; } return num; } sum(100); sum(0) 构造函数模式 构造函数模式的目的就是为了创建一个自定义类,并且创建这个类的实例

function CreateJsPerson(name, age){ this.name = name; this.age = age; this.writeJS = function(){ console.log("my name is " + this.name + ", i can write js ~~") } }

var p1 = new CreateJsPerson("lemon1", 21) var p2 = new CreateJsPerson("lemon2", 22) 构造函数和工厂模式的区别 执行的时候

普通函数执行->createJsPerson() 构造函数模式->new CreateJsPerson(), 通过new执行后,createJsPerson就是一个类了,而函数执行的返回值(p1)就是CreateJsPerson这个类的一个实例) 在函数代码执行的时候

相同:都是形成一个私有的作用域,然后形参赋值->解释->代码从上到下执行 不同:在代码执行之前,不用自己手动创建对象了,浏览器会默认创建一个对象的数据类型的值,这个对象其实就是我们当前类的一个实例 接下来,代码从上到下执行,以当前的实例为执行的主体,this代表的就是当前的实例 最后浏览器会默认的把创建的实例返回 JS中所有的类都是函数数据类型的,它通过new执行变成了一个类,但是它本身也是一个普通的函数

JS中所有的实例都死对象数据类型的

p1和p2都是CreateJsPerson这个类的实例,所以都拥有writeJs这个方法,但是不同实例之间的方法是不一样的 在类中给实例增加的属性(this.xxx = xxx)属于当前实例的私有的属性,实例和实例之间单独的个体,所以私有的属性之间是不相等的

console.log(p1.writeJs === p2.writeJs); ->false

this问题 var name = "" var res = CreateJsPerson('-lemon', -22); console.log(name); console.log(age) -> '-lemon' -> -22

这样写不是构造函数模式执行而是普通的函数执行,由于没有写return所以res = undefined, 并且CreateJsPerson这个方法中的this是window

构造函数模式(扩展) function Fn(){ this.x = 100; this.getX = function(){ console.log(this.x) } } var f1 = new Fn; f1.getX(); // 方法中的this是f1 100 var ss = f1.getX; ss(); // 方法中的this是window undefined 在构造函数模式中new Fn()执行, 如果Fn不需要传递参数的话, 后面的小括号可以省略 this的问题:在类中出现的this.xxx = xxx 中的this都是当前类的实例,而某一个属性值(方法),方法中的this需要看方法执行的时候,前面是否有"."才能知道this是谁 类有普通函数的一面,当函数执行的时候, var num其实只是当前形成的私有作用域中的私有变量而已, 它和f1这个实例没有任何关系.只有this.xxx = xxx才相当于给f1这个实例增加私有的属性和方法,才和我们的f1有关系 function Fn(){ var num = 10; this.x = 100; this.getX = function(){ console.log(this.x) } } var f1 = new Fn; console.log(f1.num); // -> undefined 在构造函数模式中,浏览器会默认的把我们的实例返回(返回的是一个对象数据类型的值),如果我们自己手动写了return返回: 返回的是一个基本数据类型的值,当前实例是不变的,例如: return 100;

返回的是一个引用数据类型的值,当前的实例会被自己返回的值替换掉,例如: return {name: 'lemon'}, 我们的f1就不在是Fn的实例了,而是对象 {name: 'lemon'}

function Fn(){ var num = 10; this.x = 100; this.getX = function(){ console.log(this.x) } return {name: 'lemon', age: 22}; } var f1 = new Fn; console.log(f1); // {name: 'lemon', age: 22} function Fn(){ var num = 10; this.x = 100; this.getX = function(){ console.log(this.x) } return 100; } var f1 = new Fn; console.log(f1); // 不变 检测属性 检测某一个实例是否属于这个类 console.log(f1 instanceof Fn); // -> true console.log(f1 instanceof Array); // -> true f1和f2都是Fn这个类的一个实例,都拥有x和getX两个属性,但是这两个属性都是各自都属性,所以 console.log(f1.getX === f2.getX); // -> false in 检测某一个属性是否属于这个对象(attr in object), 不管是私有的属性还是公有的属性, 只要存在, 用in来检测都是true console.log("getX" in f1); // -> true hasOwnProperty: 用来检测某一个属性是否为这个对象的"私有属性",这个方法只能检测私有的属性 console.log(f1.hasOwnProperty("getX")); // -> true isPrototypeOf: 用来判断指定对象object1是否存在于另一个对象object2的原型链中,是则返回true,否则返回false object1.isPrototypeOf(object2); 如果object2的原型链中包含object1,那么isPrototypeOf方法返回true 如果object2不是一个对象或者object1没有出现在object2中的原型链中,isPrototypeOf方法将返回false. 微信图片_20210625145221.jpg

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改