Javascript 工厂函数, 构造函数

932 阅读3分钟

工厂函数, 构造函数

我悟了, js 中构造函数的名字就是 js 的所谓类名

工厂函数

什么是工厂函数? 工厂函数就是专门用于创建对象的函数, 我们就称之为工厂函数

作用: 降低代码冗余度

/*
let obj = {
	name: "zs",
	age: 23,
    say: function () {
        console.log("hello world");
	}
};
let obj = {
	name: "xhx",
	age: 22,
    say: function () {
        console.log("hello world");
    }
};
*/
function createPerson(myName, myAge) {
    let obj = new Object();
    obj.name = myName;
    obj.age = myAge;
    obj.say = function () {
        console.log("hello world");
    }
    return obj;
}
let obj1 = createPerson("zs", 23);
let obj2 = createPerson("xhx", 22);
console.log(obj1);
console.log(obj2);

构造函数

朴素版构造函数
  1. 什么是构造函数
    • 构造函数和工厂函数一样, 都专门用于创建对象
    • 构造函数本质上是工厂函数的简写 (还限制了创建方式, 更专业)
  2. 构造函数和工厂函数的区别
    • 构造函数的函数名称首字母必须大写
    • 构造函数只能够通过 new 来调用
function Person(myName, myAge) {
    // let obj = new Object();  // 系统自动添加的
    // let this = obj; // 系统自动添加的
    this.name = myName;
    this.age = myAge;
    this.say = function () {
        console.log("hello world");
    }
    // return this; // 系统自动添加的
}
let obj1 = new Person("zs", 23);
let obj2 = new Person("xhx", 22);
console.log(obj1);
console.log(obj2);

当我们 new Person("zs", 23); 系统做了什么?

  1. 会在构造函数中自动创建一个对象
  2. 会自动将刚才创建的对象赋值给 this
  3. 会在构造函数的最后自动添加 return this;
  4. 注意到, 如果手动补齐构造函数中 js 自动为我们添加的部分, 那就成为了工厂函数
优化构造函数
为什么优化
  • 朴素版构造函数两个对象中的 say 方法的实现都是一样的, 但是保存到了不同的存储空间中, 这样性能不好
  • 要优化以提升性能
第一版优化

当前这种方式存在的弊端

  1. 阅读性降低了
  2. 污染了全局的命名空间
function mySay() {
    console.log("hello world");
}
function Person(myName, myAge) {
    this.name = myName;
    this.age = myAge;
    this.say = mySay;
}
let obj1 = new Person("zs", 23);
let obj2 = new Person("xhx", 22);
// 通过三等来判断两个函数名称, 表示判断两个函数是否都存储在同一块内存中
console.log(obj1.say === obj2.say); // true
第二版优化

fns 是 function name space 的缩写, hhh 这个相比第一版并没有进步很多嘛

// function mySay() {
//     console.log("hello world");
// }
let fns = {
    mySay: function () {
        console.log("hello world");
    }
}
function Person(myName, myAge) {
    this.name = myName;
    this.age = myAge;
    this.say = fns.mySay;
}
let obj1 = new Person("zs", 23);
let obj2 = new Person("xhx", 22);
console.log(obj1.say === obj2.say); // true
三版优化 (原型入门)

prototype 是对象, 在这里 prototype 是构造函数这个对象的对象

用原型做到了真正不污染, 但可读性方面存在一定门槛

我在 chrome 尝试了一下, 构造函数本质和普通函数还真是一样的

// let fns = {
//     mySay: function () {
//         console.log("hello world");
//     }
// }
function Person(myName, myAge) {
    this.name = myName;
    this.age = myAge;
}
Person.prototype = { // 用 Person.prototype.say = function (){} 也能行, 亲测能行
    say: function () {
        console.log("hello world");
    }
}
let obj1 = new Person("zs", 23);
let obj2 = new Person("xhx", 22);
console.log(obj1.say === obj2.say); // true

补充: 第十行这种被称为自定义原型对象, 第十行注释部分称为给原型对象动态添加方法