当前位置 : 主页 > 网络编程 > JavaScript >

JS创建对象常用设计模式工厂构造函数及原型

来源:互联网 收集:自由互联 发布时间:2023-02-08
目录 引言 工厂模式 构造函数模式 原型模式 结语 引言 很多工友们都说:设计模式根本用不到,然而它其实时刻就在我们身边,像王国维所说:众里寻他千百度,蓦然回首,那人正在灯
目录
  • 引言
    • 工厂模式
    • 构造函数模式
    • 原型模式
  • 结语

    引言

    很多工友们都说:设计模式根本用不到,然而它其实时刻就在我们身边,像王国维所说:众里寻他千百度,蓦然回首,那人正在灯火阑珊处。

    工厂模式

    什么是工厂模式?其实就字面意思,在现实社会生活中,市场通过不同工厂加工成不同的产品。

    转化成 JS 代码就是这样的:

    // 汽车工厂
    function carFactory(brand, price, district) {
    	 let o = new Object();
    	 o.brand= brand;
    	 o.price= price;
    	 o.district= district;
    	 o.performance= function() {
    		 console.log(this.brand);
    	 };
    	 return o;
    }
    // 生产汽车
    let car1 = carFactory("Benz", 50, "china");
    let car2= carFactory("Honda", 30, "usa");
    
    // 糖果工厂
    function candyFactory(name, size, color) {
    	 let o = new Object();
    	 o.name= name;
    	 o.size= size;
    	 o.color= color;
    	 o.performance= function() {
    		 console.log(this.name);
    	 };
    	 return o;
    }
    // 生产糖果
    let candy1= candyFactory("Oreo", "small", "white");
    let candy2= candyFactory("quduoduo", "middle", "black");
    

    有汽车工厂,糖果工厂等等,我们通过工厂函数,创建了特定对象。

    工厂模式是一种众所周知的设计模式,广泛应用于软件工程领域,用于抽象创建特定对象的过程。

    构造函数模式

    构造函数是用于创建特定类型对象的,可以自定义构造函数,以函数的形式为自己的对象类型定义属性和方法。

    比如前面的例子,就可以该写为:

    // 构造汽车的构造函数
    function Car(brand, price, district) {
    	 this.brand= brand;
    	 this.price= price;
    	 this.district= district;
    	 this.performance= function() {
    		 console.log(this.brand);
    	 };
    }
    // 构造汽车
    let car1 = new Car("Benz", 50, "china");
    let car2= new Car("Honda", 30, "usa");
    

    与工厂模式的区别是,构造函数模式:

    • 没有显式地创建对象;
    • 属性和方法直接赋值给了 this;
    • 没有 return;

    构造函数首字母通常是大写;

    这里涉及到一个重要的考点:即使用 new 会发生什么?

    官方解答:

    (1) 在内存中创建一个新对象。 (2) 这个新对象内部的[[Prototype]](隐式原型)特性被赋值为构造函数的 prototype (显示原型)属性。 (3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。 (4) 执行构造函数内部的代码(给新对象添加属性)。 (5) 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。

    这个,就是“原型链”的构造过程!!

    car1.__proto__===Car.prototype // true
    car1 instanceof Car // true
    
    • 构造函数的问题

    构造函数的主要问题在于,其定义的方法会在每个实例上都创建一遍。

    什么意思?用代码来解释:

    // 构造汽车的构造函数
    function Car(brand, price, district) {
    	 this.brand= brand;
    	 this.price= price;
    	 this.district= district;
    	 this.performance= function() {
    	 };
    }
    // 构造汽车
    let car1 = new Car("Benz", 50, "china");
    let car2= new Car("Honda", 30, "usa");
    car1.performance == car2.performance // false
    

    即使是同样的方法,也不相等,因为每次执行 new 的时候,实例的方法都是重新创建的;

    原型模式

    原型模式可以解决构造函数模式“重复创建方法”的问题。

    // 原型创建
    function Car(brand, price, district) {
    	 Car.prototype.brand= brand;
    	 Car.prototype.price= price;
    	 Car.prototype.district= district;
    	 Car.prototype.performance= function() {
    	 };
    }
    let car1 = new Car("Benz", 50, "china");
    let car2= new Car("Honda", 30, "usa");
    car1.performance === car2.performance // true
    

    这里不妨再重温一下原型链的指向关系:

    car1.__proto__===Car.prototype // true
    Car.__proto__===Function.prototype // true
    Function.prototype.__proto__===Object.prototype //true
    Car.prototype.__proto__===Object.prototype //true
    Object.prototype.__proto__===null // true
    

    原型模式弱化了向构造函数传递初始化参数的能力,会导致所有实例默认都取得相同的属性值。

    function Person() {}
    Person.prototype = {
     constructor: Person,
     friends: "A",
     sayName() {
     }
    }; 
    let person1 = new Person();
    let person2 = new Person();
    person1.friends="B";
    person1.friends // 'B'
    person2.friends // 'A'
    
    function PersonArr() {}
    PersonArr.prototype = {
     constructor: PersonArr,
     friends:["A"],
     sayName() {
     }
    }; 
    let person1 = new PersonArr();
    let person2 = new PersonArr();
    person1.friends.push("B");
    person1.friends // ["A","B"]
    person2.friends // ["A","B"]
    

    原型上的所有属性是在实例间共享的,这对函数来说比较合适。对原始值的属性 也还好,但对于引用值的属性,则会产生混乱!!

    结语

    工厂模式、构造函数模式、原型模式,这三者没有谁好谁坏,使用时,更多的是讲究一个 —— 适合!只有清楚它们的原理,才能游刃有余。

    更多关于JS创建对象设计模式的资料请关注易盾网络其它相关文章!

    上一篇:避免地狱async await的使用及原理解析
    下一篇:没有了
    网友评论