首页 > 奇闻 > 正文内容

JS中定义对象方法的最佳实践:构造函数 vs 工厂函数

奇闻2025-05-28 01:00:28

新手如何快速搞懂JS对象方法?每次看到别人的代码里既有带new的写法,又有直接返回对象的写法就懵圈?今天咱们就把这俩冤家——??构造函数??和??工厂函数??拉出来遛遛,保准你看完就知道什么时候该用谁!


一、构造函数:流水线造对象的老师傅

??举个栗子??:
想象你要开个包子铺,每天要生产100个肉包。用构造函数就像搞了个自动包包子机:

javascript复制
function Baozi(filling) {
    this.filling = filling;
    this.cook = function() {
        console.log(this.filling + "馅包子蒸好了!");
    };
}

let bao1 = new Baozi("猪肉");
bao1.cook(); // 猪肉馅包子蒸好了!

??关键特征??:

  • 必须用new关键字调用(不然this指向会发神经)
  • 方法挂在实例上(每个包子都有独立蒸笼)
  • 命名必须??首字母大写??(行业潜规则)

??你可能想问??:这和我直接写对象字面量有啥区别?
问得好!当你要批量生产相同结构的对象时,用构造函数就像开了复印机——??省时省力??。但下面这个坑一定要当心!


二、工厂函数:灵活定制的私房菜

??换个场景??:
要是顾客天天要不同口味的定制包子怎么办?这时候工厂函数就像米其林大厨:

javascript复制
function createBaozi(filling, size) {
    return {
        filling: filling,
        size: size,
        cook() {
            console.log(size + "号" + filling + "馅包子出锅啦");
        }
    };
}

let bao2 = createBaozi("蟹黄", "XL");
bao2.cook(); // XL号蟹黄馅包子出锅啦

??核心优势??:

  • 不用new,避免this指向问题(对新手更友好)
  • 可以返回任意结构的对象(想加辣就加辣)
  • 方法共享要靠其他手段(后面细说)

三、生死对决:内存消耗大比拼

??灵魂拷问??:用构造函数会不会撑爆内存?咱们做个实验:

javascript复制
// 构造函数版本
function ClassA() {
    this.method = function() {};
}
let a1 = new ClassA();
let a2 = new ClassA();
console.log(a1.method === a2.method); // false!

// 工厂函数+共享方法
const sharedMethod = function() {};
function createB() {
    return {
        method: sharedMethod
    };
}
let b1 = createB();
let b2 = createB();
console.log(b1.method === b2.method); // true!

??血泪教训??:

  • 构造函数每个实例都??自带方法副本??(内存杀手)
  • 工厂函数可以手动共享方法(但得自己记着)
  • 折中方案:构造函数+原型链(后面解释)

四、混合双打:取长补短怎么玩

??高阶技巧??:把工厂函数和原型链结合使用:

javascript复制
const proto = {
    cook() {
        console.log(this.filling + "馅包子");
    }
};

function createBaozi(filling) {
    return Object.create(proto, {
        filling: { value: filling }
    });
}

let bao3 = createBaozi("韭菜鸡蛋");
bao3.cook(); // 韭菜鸡蛋馅包子

??优势分析??:

  • 方法挂在原型上(内存友好)
  • 不用new关键字(防止手滑)
  • 支持动态修改原型(灵活度爆表)

五、现代JS的隐藏彩蛋:class语法

??你可能要问??:现在都用ES6的class了,还要学这些老古董?
其实class本质就是构造函数的语法糖:

javascript复制
class Baozi {
    constructor(filling) {
        this.filling = filling;
    }
    cook() {
        console.log(this.filling + "馅包子");
    }
}

??对比表格??:

特性构造函数工厂函数ES6 class
是否需要new???
方法存储位置实例/原型实例/手动共享原型
this指向风险
类型检测instanceof有效只能检测对象类型instanceof有效

小编观点拍板时刻

干了这么多年开发,我的血泪经验是:

  1. ??新手入门期??先用工厂函数,避开thisnew的坑
  2. ??团队协作项目??优先用class语法,符合现代开发规范
  3. ??需要极致性能??时,构造函数+原型链才是王道
  4. ??写工具库或框架??推荐工厂模式,灵活性碾压其他方案

最后说句大实话:??没有最好的方法,只有最合适的场景??。就像做包子,批量生产用机器,私房定制用手工,关键是搞清楚自己要解决什么问题!

搜索