我正在玩ES6课程,我最终的目标是了解类与构造函数和工厂函数之间的区别。我的当前理解是构造函数和类基本上使用相同的设计模式,类只是构造函数的新语法。基于这个假设,我试图创建一些示例来显示类/构造函数和工厂函数之间的对比。
通过下面的示例,我的目标是返回新对象和一些继承的方法。
我的第一个例子是类语法相当简单。
示例#1:类
class Person {
constructor(name, age, location, occupation) {
this.name = name;
this.age = age;
this.location = location;
this.occupation = occupation;
}
printDescription() {
console.log(`My name is ${this.name} and I'm ${this.age} years old. I live in ${this.location} and I work as a ${this.occupation}.`);
}
}
const firstUser = new Person('Tom', 30, 'Sydney', 'Teacher');
firstUser.printDescription();
在第二个例子中,我试图用不同的方法复制第一个例子,但我不确定这是工厂构造函数还是工厂函数。
示例#2:?
function PersonMaker (name, age, location, occupation) {
let person = {name, age, location, occupation};
person.printDetails = () => {
console.log(`My name is ${name} and I'm ${age} years old. I live in ${location} and I work as a ${occupation}.`);
};
return person;
}
const secondUser = PersonMaker('Johnny', 25, 'London', 'Driver');
secondUser.printDetails();
我需要澄清第二个例子中使用的模式,如果它不是工厂函数,我怎么把它变成一个?
答案 0 :(得分:3)
因为它返回一个对象,它是一个工厂函数 - it's already explained there。
Constuctor函数行为与此不同,它不返回值:
function Person(name, age, location, occupation){
this.name = name
this.age = age
this.location = location
this.occupation = occupation
}
Person.prototype.printDetails = function(){
console.log(`My name is ${this.name} and I'm ${this.age} years old. I live in ${this.location} and I work as a ${this.occupation}.`);
};
const secondUser = new Person('Johnny', 25, 'London', 'Driver');
secondUser.printDetails();
我通过将原型扩展到单独的构造函数来使用方法的定义,你仍然可以在构造函数中定义一个方法:
function Person(name, age, location, occupation){
this.name = name
this.age = age
this.location = location
this.occupation = occupation
this.printDetails = function(){
console.log(`My name is ${this.name} and I'm ${this.age} years old. I live in ${this.location} and I work as a ${this.occupation}.`);
};
}
const secondUser = new Person('Johnny', 25, 'London', 'Driver');
secondUser.printDetails();
答案 1 :(得分:3)
为避免传递多个参数,您可以这样做。
const PersonMaker = description => {
const {name, age, location, occupation} = description;
return {
printDetails: () => {
console.log(
`My name is ${name} and I'm ${age} years old. I live in ${location} and I work as a ${occupation}.`,
);
},
};
};
const secondUser = PersonMaker({
name: 'Johnny',
age: '25',
location: 'London',
occupation: 'Driver',
});
console.log(secondUser.printDetails());
答案 2 :(得分:1)
Javascript的根源在于Prototypal Inheritance:
// Prototype
var ProtoCtr = function ProtoCtr(name, age) {
this.name = name;
this.age = age;
};
ProtoCtr.prototype.printDetails = function printDetails() { console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old`); };
var protoInstance = new ProtoCtr('John', 21);
protoInstance.printDetails();
简而言之:
函数公开原型
定义引用实例的this
上下文
使用new
关键字创建实例
然后,使用ES6,该语言提供了使用class
关键字的可能性(以取悦古典OO开发人员)。它是一种语法,允许在块中对对象的声明进行分组,从而避免“手动”扩展原型。在引擎盖下,它与原型模型完全相同,它只是另一种写它的方式。
// Class
class ClassCtr {
constructor(name, age) {
this.name = name;
this.age = age;
}
printDetails() {
console.log(`Hi, I'm ${this.name} and I'm ${this.age} years old`);
}
}
var classInstance = new ClassCtr('John', 21);
classInstance.printDetails();
关键概念大致相同,但您不使用原型向您的实例公开方法,而是直接在class
块中声明它。
然后,有工厂模式,这不是语言规范,而是模式,是一种做事的方式。这是我个人的最爱。工厂函数构建并返回实例。使用此方法,您可以删除new
关键字,并且不再需要this
来引用您的实例:
// Factory
var factoryCtr = function factoryCtr(name, age) {
var instance = {
name: name,
age: age,
printDetails: function printDetails() { console.log(`Hi, I'm ${instance.name} and I'm ${instance.age} years old`); }
};
return instance;
}
var factoryInstance = factoryCtr('John', 21);
factoryInstance.printDetails();
即使本次演讲不涵盖课程,我建议您观看此视频: https://www.youtube.com/watch?v=ya4UHuXNygM
我希望这有助于:)