• 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.

  • 相关阅读:
    安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置
    各种编程语言的深度学习库整理
    十个开源深度学习框架
    深度学习框架的评估与比较
    Caffe 深度学习框架上手教程
    机器视觉开源代码集合
    人工智能的妙用:谷歌公布图像字幕技术
    谷歌推出最新图像识别工具Google Cloud Vision API
    机器学习常见算法分类汇总
    神经网络的分类及其应用
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13641547.html
Copyright © 2020-2023  润新知