• 工厂模式,构造函数模式,原型模式,组合模式简单理解


    我们知道创建对象常见的方式有两种:字面量方式和new 操作符方式

    字面量
    var people1 = {
    name:"小明"
    }
    new操作符
    var people2 = new Object()
    people2.name="小花"

    尽管这两种可以满足我们的基本要求,但是在创建大量类似对象时候,会产生大量的重复代码。因此我们产生了工厂模式

    function person(name,age) {
    var obj = new Object();
    obj.name = name;
    obj.age = age;
    obj.sayName = function () {
    alert(this.name)
    };
    return obj
    }
    var person1 = person('小明',12)
    console.log(person1 instanceof person)//false
    console.log(person1 instanceof Object)//true

    虽然工厂模式解决了我们创建大量对象问题,但是产生了新的问题,无法确定对象的来源问题,因此我们产生了构造函数模式

    function Person(name) {
    this.name = name;
    this.sayName = function () {
    console.log(this.name)
    }
    }
    var p1 = new Person("小明");
    var p2 = new Person("小花");
    console.log(p1 instanceof Person)//true
    console.log(p1 instanceof Object)//true
    console.log(p1.sayName===p2.sayName);//false
    p1.sayName();
    p2.sayName();

    这种方式解决了对象的来源问题,但是也有问题,每生成一个实例都会创建一个function实例,因此我们改进模式,让每个实例的方法指向同一个实例

    function Person(name) {
    this.name = name;
    this.sayName = sayName
    }
    function sayName() {
    alert(this.name)
    }
    var p1 = new Person("小明");
    var p2 = new Person("小花");
    console.log(p1.sayName===p2.sayName)//true
    但是这样在全局作用域的方法只能被Person实例化的对象使用,而且多个方法需要创建多个全局方法,这样封装性很低。于是我们产生了原型模式
    每个函数都有它的原型属性,即prototype,这个属性是一个指针,指向一个对象

    function Person() {
    };
    Person.prototype.name = "小明";
    Person.prototype.sayName = function () {
    alert(this.name)
    };
    var p1 = new Person();
    var p2 = new Person();
    console.log(p1.name);//小明
    console.log(p2.name);//小明
    console.log(p1.sayName===p2.sayName)//true
    console.log(p1 instanceof Person)//true
    原型模式既解决了对象来源问题,也解决了对象公用同一方法的问题。但是原型模式也不是没有缺点的

    function Person() {
    };
    Person.prototype.name = "小明";
    Person.prototype.family = ["小王","小张","小李"];
    Person.prototype.sayName = function () {
    alert(this.name)
    };
    var p1 = new Person();
    var p2 = new Person();

    p1.family.push("小孙")
    console.log(p1.family);//["小王", "小张", "小李", "小孙"]
    console.log(p2.family);//["小王", "小张", "小李", "小孙"]
    如上所示,每个实例都继承了原型的默认属性,当某个实例被修改时,会改变原型的,因此,p2的family也跟随改变,前提是修改他的属性而不是赋值,直接给p1的family赋值是不会改变p2的。当然你也可以通过复制原型的属性在进行操作(实际上就是赋值),但是这样显然不是我们想要的。

    let family = JSON.parse(JSON.stringify(p1.family))
    family.push("小孙");
    p1.family = family;
    console.log(p1.family);//["小王", "小张", "小李", "小孙"]
    console.log(p2.family);//["小王", "小张", "小李"]
    于是我们再次改进,这样出现了组合模式,构造函数模式和原型模式

    function Person(name) {
    this.name = name;
    this.family = ["小王","小张","小李"];
    };
    Person.prototype.age = 22;
    Person.prototype.sayName = function () {
    alert(this.name)
    };
    var p1 = new Person("小黑");
    var p2 = new Person("小明");
    p1.family.push("小红");
    console.log(p1.name);//小黑
    console.log(p2.name);//小明
    console.log(p1.age);//22
    console.log(p2.age);//22
    console.log(p1.family);//["小王", "小张", "小李", "小红"]
    console.log(p2.family);//["小王", "小张", "小李"]
    构造函数用于定义实例属性,原型用于定义共享的属性和方法,这种方法也是目前最常用的自定义类型方式。既共享方法又独立属性
    ————————————————
    版权声明:本文为CSDN博主「前端修仙」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/zfz5720/article/details/90403959

  • 相关阅读:
    MySQL大表优化方案
    写一个简单脚本检测mysql主从是否正常
    Nginx配置基于ip的虚拟主机
    推荐一些好的linux学习网站
    shell基础入门(一)
    centos7和linux防火墙配置入门
    centos7.0之vsftpd随笔
    获取系统相关属性
    linux 文件管理操作入门
    ANSI文件操作
  • 原文地址:https://www.cnblogs.com/hsdying/p/12617941.html
Copyright © 2020-2023  润新知